<!DOCTYPE html>


<html lang="zh-CN">


<head>
  <meta charset="utf-8" />
    
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
  <title>
     
  </title>
  <meta name="generator" content="hexo-theme-ayer">
  
  <link rel="shortcut icon" href="/favicon.ico" />
  
  
<link rel="stylesheet" href="/dist/main.css">

  
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/css/remixicon.min.css">

  
<link rel="stylesheet" href="/css/custom.css">

  
  
<script src="https://cdn.jsdelivr.net/npm/pace-js@1.0.2/pace.min.js"></script>

  
  

  

</head>

</html>

<body>
  <div id="app">
    
      
    <main class="content on">
      
<section class="cover">
    
      
      <a class="forkMe" href="https://github.com/Shen-Yu/hexo-theme-ayer"
        target="_blank"><img width="149" height="149" src="/images/forkme.png"
          class="attachment-full size-full" alt="Fork me on GitHub" data-recalc-dims="1"></a>
    
  <div class="cover-frame">
    <div class="bg-box">
      <img src="/images/cover1.jpg" alt="image frame" />
    </div>
    <div class="cover-inner text-center text-white">
      <h1><a href="/">Hexo</a></h1>
      <div id="subtitle-box">
        
        <span id="subtitle"></span>
        
      </div>
      <div>
        
      </div>
    </div>
  </div>
  <div class="cover-learn-more">
    <a href="javascript:void(0)" class="anchor"><i class="ri-arrow-down-line"></i></a>
  </div>
</section>



<script src="https://cdn.jsdelivr.net/npm/typed.js@2.0.11/lib/typed.min.js"></script>


<!-- Subtitle -->

  <script>
    try {
      var typed = new Typed("#subtitle", {
        strings: ['面朝大海，春暖花开', '何来天才，唯有苦练', '集中一点，登峰造极'],
        startDelay: 0,
        typeSpeed: 200,
        loop: true,
        backSpeed: 100,
        showCursor: true
      });
    } catch (err) {
      console.log(err)
    }
  </script>
  
<div id="main">
  <section class="outer">
  
  

<div class="notice" style="margin-top:50px">
    <i class="ri-heart-fill"></i>
    <div class="notice-content" id="broad"></div>
</div>
<script type="text/javascript">
    fetch('https://v1.hitokoto.cn')
        .then(response => response.json())
        .then(data => {
            document.getElementById("broad").innerHTML = data.hitokoto;
        })
        .catch(console.error)
</script>

<style>
    .notice {
        padding: 20px;
        border: 1px dashed #e6e6e6;
        color: #969696;
        position: relative;
        display: inline-block;
        width: 100%;
        background: #fbfbfb50;
        border-radius: 10px;
    }

    .notice i {
        float: left;
        color: #999;
        font-size: 16px;
        padding-right: 10px;
        vertical-align: middle;
        margin-top: -2px;
    }

    .notice-content {
        display: initial;
        vertical-align: middle;
    }
</style>
  
  <article class="articles">
    
    
    
    
    <article
  id="post-other/大公司为什么都有API网关？聊聊API网关的作用"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/11/11/other/%E5%A4%A7%E5%85%AC%E5%8F%B8%E4%B8%BA%E4%BB%80%E4%B9%88%E9%83%BD%E6%9C%89API%E7%BD%91%E5%85%B3%EF%BC%9F%E8%81%8A%E8%81%8AAPI%E7%BD%91%E5%85%B3%E7%9A%84%E4%BD%9C%E7%94%A8/"
    >大公司为什么都有API网关？聊聊API网关的作用.md</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/11/11/other/%E5%A4%A7%E5%85%AC%E5%8F%B8%E4%B8%BA%E4%BB%80%E4%B9%88%E9%83%BD%E6%9C%89API%E7%BD%91%E5%85%B3%EF%BC%9F%E8%81%8A%E8%81%8AAPI%E7%BD%91%E5%85%B3%E7%9A%84%E4%BD%9C%E7%94%A8/" class="article-date">
  <time datetime="2020-11-10T16:00:00.000Z" itemprop="datePublished">2020-11-11</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/other/">other</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h1 id="大公司为什么都有API网关？聊聊API网关的作用"><a href="#大公司为什么都有API网关？聊聊API网关的作用" class="headerlink" title="大公司为什么都有API网关？聊聊API网关的作用"></a>大公司为什么都有API网关？聊聊API网关的作用</h1><h2 id="一、API网关的用处"><a href="#一、API网关的用处" class="headerlink" title="一、API网关的用处"></a><strong>一、API网关的用处</strong></h2><p>API网关我的分析中会用到以下三种场景。</p>
<p><strong>Open API</strong></p>
<p>企业需要将自身数据、能力等作为开发平台向外开放，通常会以rest的方式向外提供，最好的例子就是淘宝开放平台、腾讯公司的QQ开发平台、微信开放平台。</p>
<p>Open API开放平台必然涉及到客户应用的接入、API权限的管理、调用次数管理等，必然会有一个统一的入口进行管理，这正是API网关可以发挥作用的时候。</p>
<p><strong>微服务网关</strong></p>
<p>微服务的概念最早在2012年提出，在Martin Fowler的大力推广下，微服务在2014年后得到了大力发展。在微服务架构中，有一个组件可以说是必不可少的，那就是微服务网关，微服务网关处理了负载均衡，缓存，路由，访问控制，服务代理，监控，日志等。API网关在微服务架构中正是以微服务网关的身份存在。</p>
<p><strong>API服务管理平台</strong></p>
<p>上述的微服务架构对企业来说有可能实施上是困难的，企业有很多遗留系统，要全部抽取为微服务器改动太大，对企业来说成本太高。但是由于不同系统间存在大量的API服务互相调用，因此需要对系统间服务调用进行管理，清晰地看到各系统调用关系，对系统间调用进行监控等。</p>
<p>API网关可以解决这些问题，我们可以认为如果没有大规模的实施微服务架构，那么对企业来说微服务网关就是企业的API服务管理平台。</p>
<h2 id="二、API网关在企业整体架构中的地位"><a href="#二、API网关在企业整体架构中的地位" class="headerlink" title="二、API网关在企业整体架构中的地位"></a><strong>二、API网关在企业整体架构中的地位</strong></h2><p>一个企业随着信息系统复杂度的提高，必然出现外部合作伙伴应用、企业自身的公网应用、企业内网应用等，在架构上应该将这三种应用区别开，三种应用的安排级别、访问方式也不一样。</p>
<p>因此在我的设计中将这三种应用分别用不同的网关进行API管理，分别是：API网关（OpenAPI合伙伙伴应用）、API网关（内部应用）、API网关（内部公网应用）。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601003343359.webp" alt="img"></p>
<h2 id="三、企业中在如何应用API网关"><a href="#三、企业中在如何应用API网关" class="headerlink" title="三、企业中在如何应用API网关"></a><strong>三、企业中在如何应用API网关</strong></h2><p>1、对于OpenAPI使用的API网关来说，一般合作伙伴要以应用的形式接入到OpenAPI平台，合作伙伴需要到 OpenAPI平台申请应用。</p>
<p>因此在OpenAPI网关之外，需要有一个面向合作伙伴的使用的平台用于合作伙伴，这就要求OpenAPI网关需要提供API给这个用户平台进行访问。</p>
<p>搜索顶级架构师公众号回复“offer”，送你一份算法面试题和答案惊喜礼包。</p>
<p>如下架构:</p>
<p><img src="http://iubest.gitee.io/pic/640-1601003343419.webp" alt="img"></p>
<p>当然如果是在简单的场景下，可能并不需要提供一个面向合作伙伴的门户，只需要由公司的运营人员直接添加合作伙伴应用id/密钥等，这种情况下也就不需要合作伙伴门户子系统。</p>
<p>2、对于内网的API网关，在起到的作用上来说可以认为是<a target="_blank" rel="noopener" href="http://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247488453&idx=2&sn=1d43c2d5932d414d358b101481b937e3&chksm=ebd62ce9dca1a5ff3aa88fcd127810bf4865d58f0f46f9bd5708c8772fa3f61a716c068dea09&scene=21#wechat_redirect">微服务网关</a>，也可以认为是内网的API服务治理平台。当企业将所有的应用使用微服务的架构管理起来，那么API网关就起到了微服务网关的作用。</p>
<p>而当企业只是将系统与系统之间的调用使用rest api的方式进行访问时使用API网关对调用进行管理，那么API网关起到的就是API服务治理的作用。</p>
<p>架构参考如下：</p>
<p><img src="http://iubest.gitee.io/pic/640-1601003343352.webp" alt="img"></p>
<p>3、对于公司内部公网应用（如APP、公司的网站），如果管理上比较细致，在架构上是可能由独立的API网关来处理这部分内部公网应用，如果想比较简单的处理，也可以是使用面向合作伙伴的API网关。</p>
<p>如果使用独立的API网关，有以下的好处：</p>
<ul>
<li>面向合作伙伴和面向公司主体业务的优先级不一样，不同的API网关可以做到业务影响的隔离。</li>
<li>内部API使用的管理流程和面向合作伙伴的管理流程可能不一样。</li>
<li>内部的API在功能扩展等方面的需求一般会大于OpenAPI对于功能的要求。</li>
</ul>
<p>基于以上的分析，如果公司有能力，那么还是建议分开使用合作伙伴OPEN API网关和内部公网应用网关。</p>
<h2 id="四、API网关有哪些竞争方案"><a href="#四、API网关有哪些竞争方案" class="headerlink" title="四、API网关有哪些竞争方案"></a><strong>四、API网关有哪些竞争方案</strong></h2><p>1、对于Open API平台的API网关，我分析只能选择API网关作为解决方案，业界没有发现比较好的可以用来作为Open API平台的入口的其他方案。</p>
<p>2、对于作为微服务网关的API网关，业界的选择可以选择的解决方案比较多，也取决于微服务器的实现方案，有一些微服务架构的实现方案是不需要微服务网关的。</p>
<p>Service Mesh，这是新兴的基于无API网关的架构，通过在客户端上的代理完成屏蔽网络层的访问，这样达到对应用层最小的改动，当前Service Mesh的产品还正在开发中，并没有非常成熟可直接应用的产品。发展最迅速的产品是Istio。建议大家密切关注相关产品的研发、业务使用进展。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601003343413.webp" alt="img"></p>
<p>基于duboo架构，在这个架构中通常是不需要网关的，是由客户端直接访问服务提供方，由注册中心向客户端返回服务方的地址。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601003343361.webp" alt="img"></p>
<h2 id="五、API网关解决方案"><a href="#五、API网关解决方案" class="headerlink" title="五、API网关解决方案"></a><strong>五、API网关解决方案</strong></h2><p>私有云开源解决方案如下：</p>
<ul>
<li>Kong kong是基于Nginx+Lua进行二次开发的方案， <a target="_blank" rel="noopener" href="https://konghq.com/">https://konghq.com/</a></li>
<li>Netflix Zuul，zuul是spring cloud的一个推荐组件，<a target="_blank" rel="noopener" href="https://github.com/Netflix/zuul">https://github.com/Netflix/zuul</a></li>
<li>orange,这个开源程序是国人开发的， <a target="_blank" rel="noopener" href="http://orange.sumory.com/">http://orange.sumory.com/</a></li>
</ul>
<p>公有云解决方案：</p>
<ul>
<li>Amazon API Gateway，<a target="_blank" rel="noopener" href="https://aws.amazon.com/cn/api-gateway/">https://aws.amazon.com/cn/api-gateway/</a></li>
<li>阿里云API网关，<a target="_blank" rel="noopener" href="https://www.aliyun.com/product/apigateway/">https://www.aliyun.com/product/apigateway/</a></li>
<li>腾讯云API网关， <a target="_blank" rel="noopener" href="https://cloud.tencent.com/product/apigateway">https://cloud.tencent.com/product/apigateway</a></li>
</ul>
<p>自开发解决方案：</p>
<ul>
<li>基于Nginx+Lua+ OpenResty的方案，可以看到Kong,orange都是基于这个方案</li>
<li>基于Netty、非阻塞IO模型。通过网上搜索可以看到国内的宜人贷等一些公司是基于这种方案，是一种成熟的方案。</li>
<li>基于Node.js的方案。这种方案是应用了Node.js天生的非阻塞的特性。</li>
<li>基于java Servlet的方案。zuul基于的就是这种方案，这种方案的效率不高，这也是zuul总是被诟病的原因。</li>
</ul>
<h2 id="六、企业怎么选择API网关"><a href="#六、企业怎么选择API网关" class="headerlink" title="六、企业怎么选择API网关"></a><strong>六、企业怎么选择API网关</strong></h2><p>如果是要选择一款已有的API网关，那么需要从以下几个方面去考虑。</p>
<p><strong>1、性能与可用性</strong></p>
<p>如果一旦采用了API网关，那么API网关就会作为企业应用核心，因此性能和可用性是必须要求的。</p>
<p> 搜索顶级架构师公众号回复“架构整洁”，送你一份惊喜礼包。</p>
<p>从性能上来说，需要让网关增加的时间消耗越短越好，个人觉得需要10ms以下。系统需要采用非阻塞的IO，如epoll，NIO等。网关和各种依赖的交互也需要是非阻塞的，这样才能保证整体系统的高可用性，如：Node.js的响应式编程和基于java体现的RxJava和Future。</p>
<p>网关必须支持集群部署，任务一台服务器的crash都应该不影响整体系统的可用性。</p>
<p>多套网关应该支持同一管理平台和同一监控中心。如：一个企业的OpenAPI网关和内部应用的多个系统群的不同的微服务网关可以在同一监控中心进行监控。</p>
<p><strong>2、可扩展性、可维护性</strong></p>
<p>一款产品总有不能满足生产需求的地方，因此需求思考产品在如何进行二次开发和维护，是否方便公司团队接手维护产品。</p>
<p><strong>3、需求匹配度</strong></p>
<p>需要评估各API网关在需求上是否能满足，如：如果是OpenAPI平台需要使用API网关，那么需要看API网关在合作伙伴应用接入、合作伙伴门户集成、访问次数限额等OpenAPI核心需求上去思考产品是否能满足要求。如果是微服务网关，那么要从微服务的运维、监控、管理等方面去思考产品是否足够强大。</p>
<p><strong>4、是否开源？公司是否有自开发的能力？</strong></p>
<p>现有的开源产品如kong，zuul，orange都有基础的API网关的核心功能，这些开源产品大多离很好的使用有一定的距离，如：没有提供管理功能的UI界面、监控功能弱小，不支持OpenAPI平台，没有公司运营与运维的功能等。当然开源产品能获取源代码，如果公司有比较强的研发能力，能hold住这些开源产品，经过二次开发kong、zuul应该还是适应一些公司，不过需求注意以下一些点：</p>
<ul>
<li>kong是基于ngnix+lua的，从公司的角度比较难于找到能去维护这种架构产品的人。需求评估当前公司是否有这个能力去维护这个产品。</li>
<li>zuul因为架构的原因在高并发的情况下性能不高，同时需要去基于研究整合开源的适配zuul的监控和管理系统。</li>
<li>orange由于没有被大量使用，同时是国内个人在开源，在可持续性和社区资源上不够丰富，出了问题后可能不容易找到人问。</li>
</ul>
<p>另外kong提供企业版本的API网关，当然也是基于ngnix+lua的，企业版本可以购买他们的技术支持、培训等服务、以及拥有界面的管理、监控等功能。</p>
<p><strong>5、公有云还是私有云</strong></p>
<p>现在的亚马逊、阿里、腾讯云都在提供基础公有云的API网关，当然这些网关的基础功能肯定是没有问题，但是二次开发，扩展功能、监控功能可能就不能满足部分用户的定制需求了。另外很多企业因为自身信息安全的原因，不能使用外网公有网的API网关服务，这样就只有选择私有云的方案了。</p>
<p>在需求上如果基于公有云的API网关只能做到由内部人员为外网人员申请应用，无法做到定制的合作伙伴门户，这也不适合于部分企业的需求。</p>
<p>如果作为微服务网关，大多数情况下是希望网关服务器和服务提供方服务器是要在内网的，在这里情况下也只有私有云的API网关才能满足需求。</p>
<p>综合上面的分析，基础公有云的API网关只有满足一部分简单客户的需求，对于很多企业来说私有云的API网关才是正确的选择。</p>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/other/" rel="tag">other</a></li></ul>

    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-other/如何友好的把Python和Bash结合在一起"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/11/11/other/%E5%A6%82%E4%BD%95%E5%8F%8B%E5%A5%BD%E7%9A%84%E6%8A%8APython%E5%92%8CBash%E7%BB%93%E5%90%88%E5%9C%A8%E4%B8%80%E8%B5%B7/"
    >如何友好的把Python和Bash结合在一起.md</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/11/11/other/%E5%A6%82%E4%BD%95%E5%8F%8B%E5%A5%BD%E7%9A%84%E6%8A%8APython%E5%92%8CBash%E7%BB%93%E5%90%88%E5%9C%A8%E4%B8%80%E8%B5%B7/" class="article-date">
  <time datetime="2020-11-10T16:00:00.000Z" itemprop="datePublished">2020-11-11</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/other/">other</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h1 id="如何友好的把Python和Bash结合在一起"><a href="#如何友好的把Python和Bash结合在一起" class="headerlink" title="如何友好的把Python和Bash结合在一起"></a>如何友好的把Python和Bash结合在一起</h1><p>对于Linux用户而言，命令行操作我们已经非常熟悉了。与其他流行的操作系统不同，在Linux社区中，使用命令行与使用图形用户界面执行类似任务相比，命令行通常可以提供更优雅，更有效的解决方案。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601004011096.webp" alt="img"></p>
<p>随着Linux社区对命令行的依赖不断增长，UNIX shell（如bash和zsh）已发展成为极其强大的工具，可以补充UNIX shell的经验。使用bash和其他类似的shell，可以使用许多强大的功能，例如管道，文件名通配符以及从称为脚本的文件中读取命令的功能。</p>
<p>让我们看一个真实的示例来演示命令行的功能。每次用户登录服务时，其用户名都会记录到一个文本文件中。对于此示例，让我们找出有多少唯一用户使用该服务。</p>
<p>以下示例中的一系列命令通过将较小的构建块链接在一起，显示了更复杂的实用工具的功能：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ cat names.log | sort | uniq | wc -l</span><br></pre></td></tr></table></figure>

<p>管道符号（|）用于将一个命令的标准输出传递到下一命令的标准输入。在此处的示例中，cat names.txt的输出传递到sort命令中。sort命令的输出是按字母顺序重新排列文件的每一行。随后将其传递给uniq命令，该命令将删除所有重复的名称。最后，uniq的输出传递到wc命令。wc是计数命令，并且设置了-l标志，它返回行数。这使您可以将许多命令链接在一起。</p>
<p>但是，有时所需的内容可能会变得非常复杂，并且将命令链接在一起可能变得笨拙。在这种情况下，shell脚本就是答案。Shell脚本是由Shell读取并按顺序执行的命令列表。Shell脚本还支持某些编程语言基础知识，例如变量，流控制和数据结构。Shell脚本对于将经常重复运行的批处理作业非常有用。不幸的是，shell脚本有一些缺点：</p>
<p>Shell脚本很容易变得过于复杂，并且对于想要改进或维护它们的开发人员来说是不可读的。</p>
<p>这些shell脚本的语法和解释器通常很笨拙且不直观。语法越笨拙，对于必须使用这些脚本的开发人员来说，可读性就越差。</p>
<p>该代码通常无法在其他脚本中使用。脚本之间的代码重用往往很困难，并且脚本往往非常特定于某个问题。</p>
<p>用于高级功能（例如HTML解析或HTTP请求）的库不像现代编程和脚本语言那样容易获得。</p>
<p>这些问题会使shell脚本难以处理，并经常导致大量开发人员时间浪费。取而代之的是，Python编程语言可以用作非常有力的替代品。使用Python代替Shell脚本有很多好处：</p>
<p>默认情况下，所有主要的Linux发行版都安装了Python。打开命令行并立即键入python，将使您进入Python解释器。这种普遍性使它成为大多数脚本任务的明智选择。</p>
<p>Python具有非常易于阅读和理解的语法。它的风格强调简约和简洁的代码，同时允许开发人员以适合shell脚本的准系统风格进行编写。</p>
<p>Python是一种解释型语言，这意味着没有编译阶段。这使Python成为编写脚本的理想语言,它允许您以解释的方式快速尝试新代码。这使开发人员可以快速修改，而不必将整个程序写到文件中。</p>
<p>Python是一种功能齐全的编程语言。代码重用很简单，因为Python模块可以轻松导入并在任何Python脚本中使用。脚本可以轻松扩展或构建。</p>
<p>Python可以使用出色的标准库和数以千计的第三方库来处理各种高级实用程序，例如解析器和请求库。例如，Python的标准库包括日期时间库，该库允许将日期解析为指定的任何格式并将其与其他日期轻松比较。</p>
<p>但Python不应替换所有bash命令。编写以UNIX方式运行的Python程序（即读入标准输入并写入标准输出）与为现有的shell命令（如cat和sort）编写Python替代品一样强大。</p>
<p>让我们以本文前面已解决的问题为基础。除了已经完成的工作之外，让我们找出某个用户已登录系统的次数。uniq命令仅删除重复项，但不提供有关有多少重复项的信息。代替uniq，Python脚本可以用作链中的另一个命令。这是一个执行此操作的Python程序（在我的示例中，我将此文件称为namescount.py）：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">#!&#x2F;usr&#x2F;bin&#x2F;env python</span><br><span class="line">import sys</span><br><span class="line"></span><br><span class="line">if __name__ &#x3D;&#x3D; &quot;__main__&quot;:</span><br><span class="line">    # Initialize a names dictionary as empty to start with.</span><br><span class="line">    # Each key in this dictionary will be a name and the value</span><br><span class="line">    # will be the number of times that name appears.</span><br><span class="line">    names &#x3D; &#123;&#125;</span><br><span class="line">    # sys.stdin is a file object. All the same functions that</span><br><span class="line">    # can be applied to a file object can be applied to sys.stdin.</span><br><span class="line">    for name in sys.stdin.readlines():</span><br><span class="line">            # Each line will have a newline on the end</span><br><span class="line">            # that should be removed.</span><br><span class="line">            name &#x3D; name.strip()</span><br><span class="line">            if name in names:</span><br><span class="line">                    names[name] +&#x3D; 1</span><br><span class="line">            else:</span><br><span class="line">                    names[name] &#x3D; 1</span><br><span class="line"></span><br><span class="line">    # Iterating over the dictionary,</span><br><span class="line">    # print name followed by a space followed by the</span><br><span class="line">    # number of times it appeared.</span><br><span class="line">    for name, count in names.iteritems():</span><br><span class="line">            sys.stdout.write(&quot;%d\t%s\n&quot; % (count, name))</span><br></pre></td></tr></table></figure>

<p>让我们看看这个Python脚本如何适合命令链。首先，它从通过<code>sys.stdin</code>对象公开的标准输入中读取输入。任何输出都将写入<code>sys.stdout</code>对象，这是在Python中实现标准输出的方式。Python字典（在其他语言中通常称为哈希映射）用于获取从用户名到重复计数的映射。要获得所有用户的数量，请执行以下操作：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ cat names.log | python namescount.py</span><br></pre></td></tr></table></figure>

<p>显示用户出现的次数以及用户名的计数。接下来要做的是按顺序显示最常使用该系统的用户。这可以在Python级别完成，但是让我们使用核心UNIX实用程序已经提供的实用程序来实现它。以前，我使用<code>sort</code>命令对字母进行排序。如果命令提供了<code>-rn</code>标志，它将按降序对行进行数字排序。随着Python脚本按标准输出，只需将命令通过管道传递到<code>sort</code>并检索所需的输出：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ cat names.log | python namescount.py | sort -rn</span><br></pre></td></tr></table></figure>

<p>这是将Python用作命令链一部分的强大示例。在这种情况下使用Python的优点如下：</p>
<ul>
<li>与cat和sort等工具链接的能力。简单的实用程序（逐行读取文件并以数字方式对文件进行排序）由久经考验的UNIX命令处理。这些命令也逐行读取，这意味着这些功能可以缩放到大型文件，而且速度很快。</li>
<li>当需要在链中进行一些繁重的工作时，可以编写一个非常清晰，简洁的Python脚本，该脚本将执行其所需的工作，然后将责任转移给链中的下一个链接。</li>
<li>它是一个可重用的模块，尽管此示例专门针对名称，但是如果您向此输入中包含重复行的任何输入，它将打印出每行和重复的数量。通过将Python代码模块化，可以将其应用于各种场景。</li>
</ul>
<p>为了展示以模块化和管道方式组合Python脚本的强大功能，让我们进一步把问题放大。让我们找到该服务的前五名用户。<code>head</code>是一个命令，它允许您指定一定数量的行以显示给定的标准输入。将其添加到命令链中将得到以下内容：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ cat names.log | python namescount.py | sort -rn | head -n 5</span><br></pre></td></tr></table></figure>

<p>这仅显示前五个用户，而忽略其余用户。同样，要使五个用户最少使用该服务，可以使用<code>tail</code>命令，该命令采用相同的参数。将Python命令打印到标准输出的结果使可以构建和扩展其功能。</p>
<p>以上就是简单的介绍，实际中大家灵活运用就好。</p>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/other/" rel="tag">other</a></li></ul>

    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-other/裸金属究竟是个啥"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/11/11/other/%E8%A3%B8%E9%87%91%E5%B1%9E%E7%A9%B6%E7%AB%9F%E6%98%AF%E4%B8%AA%E5%95%A5/"
    >裸金属究竟是个啥.md</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/11/11/other/%E8%A3%B8%E9%87%91%E5%B1%9E%E7%A9%B6%E7%AB%9F%E6%98%AF%E4%B8%AA%E5%95%A5/" class="article-date">
  <time datetime="2020-11-10T16:00:00.000Z" itemprop="datePublished">2020-11-11</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/other/">other</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h2 id="裸金属究竟是个啥"><a href="#裸金属究竟是个啥" class="headerlink" title="裸金属究竟是个啥"></a>裸金属究竟是个啥</h2><p>原创 DavyCloud <a href="javascript:void(0);">云计算实验室</a> <em>3天前</em></p>
<p>收录于话题</p>
<p>#云计算知识点</p>
<p>1个</p>
<h2 id="什么是裸金属"><a href="#什么是裸金属" class="headerlink" title="什么是裸金属"></a>什么是裸金属</h2><p>裸金属，是英文 <strong>Bare Metal</strong> 的直译，其实也是可以叫 <strong>Bare Machine</strong> 的，可能大家觉得 Metal 听起来更酷一点，所以都爱这么叫。</p>
<p>如果说裸金属听起来有点懵逼，那么说裸机大家都很好理解了，就是指<strong>没有操作系统的计算机硬件</strong>。</p>
<p>大家伙平时在说起服务器（Server）的时候，大多数默认有一个操作系统，比如 “我有一台高性能 Linux 服务器”；还有少部分情况我们指的是品牌或者硬件配置，例如 “公司刚买了一批 Dell 服务器”。为了有所区分，对于后者，我们日常中更常见的说法是机器（Machine）。</p>
<p>Machine 就可以了，为啥要多出一个 Bare ？</p>
<p>根据 wiki 的解释，裸金属是指可以不经过操作系统干预的情况下，直接在逻辑硬件上执行指令。</p>
<blockquote>
<p>In computer science, <strong>bare machine</strong> (or <strong>bare metal</strong>) refers to a computer executing instructions directly on logic hardware without an intervening operating system.</p>
</blockquote>
<p>Bare，正是强调了直面硬件，中间并无遮拦，裸裎相见。</p>
<h2 id="为什么裸金属在云上流行"><a href="#为什么裸金属在云上流行" class="headerlink" title="为什么裸金属在云上流行"></a>为什么裸金属在云上流行</h2><p>大约从 2017 年开始，裸金属逐渐成为了云平台的标配，大大小小的云计算厂商基本都提供了裸金属服务。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601002056489.png" alt="img">云厂商的裸金属服务</p>
<p>常见的疑问有两个：</p>
<p>在虚拟化，容器化的大趋势下，为什么我们还需要裸金属？它和主流云服务器（虚拟机）有何优势呢？</p>
<p>相较于传统的 IDC 方式托管物理服务器，云上的裸金属又有哪些不同和优势呢？</p>
<p>事实上就是要理清楚<strong>裸金属</strong>、<strong>虚拟机</strong>和<strong>物理机</strong>它们之间的区别和特点。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601002056813.png" alt="img">裸金属和虚机物理机的关系</p>
<h2 id="裸金属的特点和优势"><a href="#裸金属的特点和优势" class="headerlink" title="裸金属的特点和优势"></a>裸金属的特点和优势</h2><p>这里直接借用阿里云裸金属产品页的特性介绍，主要包括 4 个方面：</p>
<p><img src="http://iubest.gitee.io/pic/640-1601002056815.png" alt="img">裸金属的优势</p>
<h3 id="安全方面"><a href="#安全方面" class="headerlink" title="安全方面"></a>安全方面</h3><p>裸金属服务器具有安全物理隔离的特性，裸金属服务器与其他租户物理隔离。</p>
<p>对安全性要求比较高的用户，例如金融类用户，他们对服务器的安全合规是有硬性要求的，裸金属服务器具有物理机级别的隔离。</p>
<h3 id="性能方面"><a href="#性能方面" class="headerlink" title="性能方面"></a>性能方面</h3><p>裸金属资源完全独占，完全没有性能损耗，能够胜任高 IO 应用、高性能计算等业务，例如海量数据采集和挖掘，高性能数据库，大型在线游戏等。</p>
<p>特别的，裸金属服务器还可以支持虚拟化，用户可以在裸金属上搭建自己的虚拟化平台，打造独占的私有云或容器云，实现「在公有云上搭建专有云」这样灵活的架构。</p>
<h3 id="弹性和自动化"><a href="#弹性和自动化" class="headerlink" title="弹性和自动化"></a>弹性和自动化</h3><p>除了裸金属的固有特性，裸金属云完全继承了虚拟化云服务器的 <strong>云</strong> 特性，例如，快速交付，弹性伸缩等，并且整个过程都是自动化管理。</p>
<p>唯一的差距在于相对于虚机和容器的秒级响应，裸金属是分钟级别的响应。</p>
<h3 id="兼容其它云产品"><a href="#兼容其它云产品" class="headerlink" title="兼容其它云产品"></a>兼容其它云产品</h3><p>裸金属作为云中居民，可以和其它云产品如云主机、云网络、云存储、云数据库直接打通，方便业务使用，构建更加灵活的整体架构和方案。</p>
<h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>从上面的内容可以看出：</p>
<p>裸金属的前两个优势是相对虚拟机的，相对于虚机，裸金属体现出了物理机的特性；</p>
<p>后两个优势是相对传统物理机的，相对于物理机，裸金属又能体现虚拟机弹性的特点。</p>
<p>因此综合来说，裸金属汲取了两家之长，受到重视也就不足为怪了。</p>
<h2 id="裸金属和容器"><a href="#裸金属和容器" class="headerlink" title="裸金属和容器"></a>裸金属和容器</h2><p>裸金属虽然性能优越又兼具弹性，但是要独占硬件，而且主流的厂商的销售方案基本都是包月，没有像虚机那样可以按使用量收费，达到按秒计费。所以价格昂贵，不是一般用户能消费的起。</p>
<p>不过，裸金属可以以另一种方式为更广大的用户提供计算服务，那就是容器。</p>
<p>容器发展之初，正是虚拟机主打的云计算热门之时，彼时的常见做法是在虚机上启动容器。随着技术的发展，特别是以 Kubernetes 为主的容器编排系统面世之后，人们发现在裸金属上运行容器更加自然。不仅性能更好，而且不用额外管理复杂的虚机化层。</p>
<p>Gartner 曾在 2015 年 9 月发布过一个咨询报告，标题是《Market Trends: The Rise of Bare-Metal Cloud and Containers》，认为未来的云计算基础设施，可能是裸金属+容器的趋势。</p>
<p>这篇报告里预测，未来的市场会向两级分化：</p>
<ul>
<li>互联网开发者的市场，追求速度、敏捷和可移植性 —— 选择容器。</li>
<li>企业应用市场，仍然希望使用可靠、安全的环境 —— 选择裸金属。</li>
</ul>
<p>于是得出这样的结论，裸金属 + 容器才是最好的组合。</p>
<p>今天看来这个预测还是靠谱的，阿里云和华为云在今年都发布了裸金属容器产品，非常值得关注。</p>
<h2 id="裸金属的技术实现"><a href="#裸金属的技术实现" class="headerlink" title="裸金属的技术实现"></a>裸金属的技术实现</h2><p>裸金属的技术实现通常需要硬件上的配合，目前只有一些头部大厂有实力做到，例如阿里云的神龙架构。</p>
<p>没有足够研发实力的企业如果想要部署裸金属云，或者更加深入的了解一些技术细节，开源 IaaS 项目 OpenStack 当然是最佳选择。</p>
<p>Ironic 是 OpenStack 中实现裸金属服务的项目，它从 Icehouse 版本开始孵化，并在 Juno 版与 Nova 进行集成。在 Kilo 版开始正式的集成到 OpenStack 项目中来，通过 Nova 调用 Ironic 的 API 来实现对物理机资源的管理和控制。</p>
<p>随后的版本演进中，Ironic 逐渐成熟，并越来越凸显它重要的地位，频频出现在版本发布亮点中。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601002056815.png" alt="img">Newton版本的OpenStack</p>
<p>在 Newton 版本的发布标题中，裸金属第一次站在虚拟化和容器中间出镜，旨在宣言 OpenStack 是一个一体化的平台。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601002056812.png" alt="img">Rocky版本的OpenStack</p>
<p>到 Rocky 版本，裸金属已经作为标题主打，并且用到的说法是 focuses on，其在基础设施层的重要性和热度已经不言而喻。</p>
<p>特别有趣的是这个项目名字，让我不禁猜想，是不是在创立项目之初，大佬们已经预见了今日局面呢？干了这么多年的虚拟化，没想到最终反过来要去革虚拟化的命。</p>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/other/" rel="tag">other</a></li></ul>

    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-tips/130个实用的网站"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/11/11/tips/130%E4%B8%AA%E5%AE%9E%E7%94%A8%E7%9A%84%E7%BD%91%E7%AB%99/"
    >130个实用的网站.md</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/11/11/tips/130%E4%B8%AA%E5%AE%9E%E7%94%A8%E7%9A%84%E7%BD%91%E7%AB%99/" class="article-date">
  <time datetime="2020-11-10T16:00:00.000Z" itemprop="datePublished">2020-11-11</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/tips/">tips</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h1 id="130个实用的网站"><a href="#130个实用的网站" class="headerlink" title="130个实用的网站"></a>130个实用的网站</h1><h2 id="搞学习"><a href="#搞学习" class="headerlink" title="搞学习"></a><strong>搞学习</strong></h2><ul>
<li>知乎：<a target="_blank" rel="noopener" href="http://www.zhihu.com/">www.zhihu.com</a></li>
<li>TED（最优质的演讲）：<a target="_blank" rel="noopener" href="https://www.ted.com/">https://www.ted.com/</a></li>
<li>大学资源网：<a target="_blank" rel="noopener" href="http://www.dxzy163.com/">http://www.dxzy163.com/</a></li>
<li>简答题：<a target="_blank" rel="noopener" href="http://www.jiandati.com/">http://www.jiandati.com/</a></li>
<li>网易公开课：<a target="_blank" rel="noopener" href="https://open.163.com/ted/">https://open.163.com/ted/</a></li>
<li>网易云课堂：<a target="_blank" rel="noopener" href="https://study.163.com/">https://study.163.com/</a></li>
<li>中国大学MOOC：<a target="_blank" rel="noopener" href="http://www.icourse163.org/">www.icourse163.org</a></li>
<li>网易云课堂：<a href="%E7%BD%91%E6%98%93%E4%BA%91%E8%AF%BE%E5%A0%82">study.163.com</a></li>
<li>哔哩哔哩弹幕网：<a target="_blank" rel="noopener" href="http://www.bilibili.com/">www.bilibili.com</a></li>
<li>我要自学网：<a target="_blank" rel="noopener" href="http://www.51zxw.net/">www.51zxw.net</a></li>
<li>学堂在线：<a target="_blank" rel="noopener" href="http://www.xuetangx.com/">www.xuetangx.com</a></li>
<li>爱课程：<a target="_blank" rel="noopener" href="http://www.icourses.cn/">www.icourses.cn</a></li>
<li>猫咪论文：<a target="_blank" rel="noopener" href="https://lunwen.im/">https://lunwen.im/</a></li>
<li>iData（论文搜索）：<a target="_blank" rel="noopener" href="http://www.cn-ki.net/">www.cn-ki.net</a></li>
<li>文泉考试：<a target="_blank" rel="noopener" href="https://www.wqkaoshi.com/">https://www.wqkaoshi.com</a></li>
<li>码农之家（计算机电子书下载）：<a target="_blank" rel="noopener" href="http://www.xz577.com/">www.xz577.com</a></li>
<li>鸠摩搜书：<a target="_blank" rel="noopener" href="http://www.jiumodiary.com/">www.jiumodiary.com</a></li>
<li>云海电子图书馆：<a target="_blank" rel="noopener" href="http://www.pdfbook.cn/">www.pdfbook.cn</a></li>
<li>周读（书籍搜索）：ireadweek.com</li>
<li>知轩藏书：<a target="_blank" rel="noopener" href="http://www.zxcs.me/">http://www.zxcs.me/</a></li>
<li>脚本之家电子书下载：<a target="_blank" rel="noopener" href="https://www.jb51.net/books/">https://www.jb51.net/books/</a></li>
<li>搜书VIP-电子书搜索：<a target="_blank" rel="noopener" href="http://www.soshuvip.com/all.html">http://www.soshuvip.com/all.html</a></li>
<li>书格（在线古籍图书馆）：<a target="_blank" rel="noopener" href="https://new.shuge.org/">https://new.shuge.org/</a></li>
<li>术语在线：<a target="_blank" rel="noopener" href="http://www.termonline.cn/">http://www.termonline.cn/</a></li>
<li>必看网（人生必看的书籍）：<a target="_blank" rel="noopener" href="https://www.biikan.com/">https://www.biikan.com/</a></li>
</ul>
<h2 id="冷知识-黑科技"><a href="#冷知识-黑科技" class="headerlink" title="冷知识 / 黑科技"></a><strong>冷知识 / 黑科技</strong></h2><ul>
<li>上班摸鱼必备（假装电脑系统升级）：<a target="_blank" rel="noopener" href="http://fakeupdate.net/">http://fakeupdate.net/</a></li>
<li>创意光线绘画：<a target="_blank" rel="noopener" href="http://weavesilk.com/">http://weavesilk.com/</a></li>
<li>星系观察：<a target="_blank" rel="noopener" href="https://stellarium-web.org/">https://stellarium-web.org/</a></li>
<li>煎蛋：<a target="_blank" rel="noopener" href="http://jandan.net/">http://jandan.net/</a></li>
<li>渣男-说话的艺术：<a target="_blank" rel="noopener" href="https://lovelive.tools/">https://lovelive.tools/</a></li>
<li>全历史：<a target="_blank" rel="noopener" href="https://www.allhistory.com/">https://www.allhistory.com/</a></li>
<li>iData：<a target="_blank" rel="noopener" href="https://www.cn-ki.net/">https://www.cn-ki.net/</a></li>
<li>caj云阅读：<a target="_blank" rel="noopener" href="http://cajviewer.cnki.net/cajcloud/">http://cajviewer.cnki.net/cajcloud/</a></li>
</ul>
<h2 id="资源搜索"><a href="#资源搜索" class="headerlink" title="资源搜索"></a><strong>资源搜索</strong></h2><ul>
<li>DogeDoge搜索引擎：<a target="_blank" rel="noopener" href="http://www.dogedoge.com/">www.dogedoge.com</a></li>
<li>秘迹搜索：<a target="_blank" rel="noopener" href="https://mijisou.com/">https://mijisou.com/</a></li>
<li>小白盘：<a target="_blank" rel="noopener" href="https://www.xiaobaipan.com/">https://www.xiaobaipan.com/</a></li>
<li>云盘精灵（资源搜索）：<a target="_blank" rel="noopener" href="http://www.yunpanjingling.com/">www.yunpanjingling.com</a></li>
<li>虫部落（资源搜索）：<a target="_blank" rel="noopener" href="http://www.chongbuluo.com/">www.chongbuluo.com</a></li>
<li>如风搜（资源搜索）：<a target="_blank" rel="noopener" href="http://www.rufengso.net/">http://www.rufengso.net/</a></li>
<li>爱扒：<a target="_blank" rel="noopener" href="https://www.zyboe.com/">https://www.zyboe.com/</a></li>
</ul>
<h2 id="小工具"><a href="#小工具" class="headerlink" title="小工具"></a><strong>小工具</strong></h2><ul>
<li>云端超级应用空间（PS，PPT，Excel，Ai）：<a target="_blank" rel="noopener" href="https://uzer.me/">https://uzer.me/</a></li>
<li>在线接口测试（Getman）：<a target="_blank" rel="noopener" href="https://getman.cn/">https://getman.cn/</a></li>
<li>香当网（年终总结，个人简历，事迹材料，租赁合同，演讲稿）：<a target="_blank" rel="noopener" href="https://www.xiangdang.net/">https://www.xiangdang.net/</a></li>
<li>二维码生成：<a target="_blank" rel="noopener" href="https://cli.im/">https://cli.im/</a></li>
<li>搜狗翻译：fanyi.sogou.com</li>
<li>熵数（图表制作，数据可视化）：<a target="_blank" rel="noopener" href="https://dydata.io/appv2/#/pages/index/home">https://dydata.io/appv2/#/pages/index/home</a></li>
<li>拷贝兔：<a target="_blank" rel="noopener" href="https://cp.anyknew.com/">https://cp.anyknew.com/</a></li>
<li>图片无限变放大：<a target="_blank" rel="noopener" href="http://bigjpg.com/zh">http://bigjpg.com/zh</a></li>
<li>幕布（在线大纲笔记工具）：mubu.com</li>
<li>奶牛快传（在线传输文件利器）：cowtransfer.com</li>
<li>在线转换器（在线转换器转换任何测量单位）：<a target="_blank" rel="noopener" href="https://zh.justcnw.com/">https://zh.justcnw.com/</a></li>
<li>调查问卷制作：<a target="_blank" rel="noopener" href="https://www.wenjuan.com/">https://www.wenjuan.com/</a></li>
<li>果核剥壳（软件下载）：<a target="_blank" rel="noopener" href="https://www.ghpym.com/">https://www.ghpym.com/</a></li>
<li>软件下载：<a target="_blank" rel="noopener" href="https://www.unyoo.com/">https://www.unyoo.com/</a></li>
<li>MSDN我告诉你（windows10系统镜像下载）：<a target="_blank" rel="noopener" href="https://msdn.itellyou.cn/">https://msdn.itellyou.cn/</a></li>
</ul>
<h2 id="工具集"><a href="#工具集" class="headerlink" title="工具集"></a>工具集</h2><ul>
<li>NiceTool.net 好工具网：<a target="_blank" rel="noopener" href="http://www.nicetool.net/">http://www.nicetool.net/</a></li>
<li>现实君工具箱（综合型在线工具集成网站）：<a target="_blank" rel="noopener" href="http://tool.uixsj.cn/">http://tool.uixsj.cn/</a></li>
<li>蓝调网站：<a target="_blank" rel="noopener" href="http://lcoc.top/">http://lcoc.top/</a></li>
<li>偷渡鱼：<a target="_blank" rel="noopener" href="https://touduyu.com/">https://touduyu.com/</a></li>
<li>牛导航：<a target="_blank" rel="noopener" href="http://www.ziliao6.com/">http://www.ziliao6.com/</a></li>
<li>小呆导航：<a target="_blank" rel="noopener" href="https://www.webjike.com/index.html">https://www.webjike.com/index.html</a></li>
<li>简法主页：<a target="_blank" rel="noopener" href="http://www.jianfast.com/">http://www.jianfast.com/</a></li>
<li>KIM主页：<a target="_blank" rel="noopener" href="https://kim.plopco.com/">https://kim.plopco.com/</a></li>
<li>聚BT：<a target="_blank" rel="noopener" href="https://jubt.net/cn/index.html">https://jubt.net/cn/index.html</a></li>
<li>精准云工具合集：<a target="_blank" rel="noopener" href="https://jingzhunyun.com/">https://jingzhunyun.com/</a></li>
<li>兔2工具合集：<a target="_blank" rel="noopener" href="https://www.tool2.cn/">https://www.tool2.cn/</a></li>
<li>爱资料工具（在线实用工具集合）：<a target="_blank" rel="noopener" href="http://www.toolnb.com/">www.toolnb.com</a></li>
<li>工具导航：<a target="_blank" rel="noopener" href="https://hao.logosc.cn/">https://hao.logosc.cn/</a></li>
</ul>
<h2 id="看视频"><a href="#看视频" class="headerlink" title="看视频"></a><strong>看视频</strong></h2><ul>
<li>电影推荐（分类别致）：<a target="_blank" rel="noopener" href="http://www.mvcat.com/">http://www.mvcat.com</a></li>
<li>去看TV：<a target="_blank" rel="noopener" href="https://www.qukantv.net/">https://www.qukantv.net/</a></li>
<li>动漫视频网：<a target="_blank" rel="noopener" href="http://www.zzzfun.com/">http://www.zzzfun.com/</a></li>
<li>94神马电影网：<a target="_blank" rel="noopener" href="http://www.9rmb.com/">http://www.9rmb.com/</a></li>
<li>NO视频官网：<a target="_blank" rel="noopener" href="http://www.novipnoad.com/">http://www.novipnoad.com/</a></li>
<li>蓝光画质电影：<a target="_blank" rel="noopener" href="http://www.languang.co/">http://www.languang.co/</a></li>
<li>在线看剧：<a target="_blank" rel="noopener" href="http://dy.27234.cn/">http://dy.27234.cn/</a></li>
<li>大数据导航：<a target="_blank" rel="noopener" href="http://hao.199it.com/">http://hao.199it.com/</a></li>
<li>多功能图片网站：<a target="_blank" rel="noopener" href="https://www.logosc.cn/so/">https://www.logosc.cn/so/</a></li>
<li>牛牛TV：<a target="_blank" rel="noopener" href="http://www.ziliao6.com/tv/">http://www.ziliao6.com/tv/</a></li>
<li>VideoFk解析视频：<a target="_blank" rel="noopener" href="http://www.videofk.com/">http://www.videofk.com/</a></li>
<li>蓝调网站：<a target="_blank" rel="noopener" href="http://lcoc.top/vip2.3/">http://lcoc.top/vip2.3/</a></li>
</ul>
<h2 id="学设计"><a href="#学设计" class="headerlink" title="学设计"></a><strong>学设计</strong></h2><ul>
<li>免费音频素材：<a target="_blank" rel="noopener" href="https://icons8.cn/music">https://icons8.cn/music</a></li>
<li>新CG儿（视频素材模板，无水印+免费下载）：<a target="_blank" rel="noopener" href="https://www.newcger.com/">https://www.newcger.com/</a></li>
<li>小图标下载：<a target="_blank" rel="noopener" href="https://www.easyicon.net/">https://www.easyicon.net/</a></li>
<li>第一字体转换器：<a target="_blank" rel="noopener" href="http://www.diyiziti.com/">http://www.diyiziti.com/</a></li>
<li>doyoudosh（平面设计）：<a target="_blank" rel="noopener" href="http://www.doyoudo.com/">www.doyoudo.com</a></li>
<li>企业宣传视频在线制作：<a target="_blank" rel="noopener" href="https://duomu.tv/">https://duomu.tv/</a></li>
<li>MAKE海报设计官网：<a target="_blank" rel="noopener" href="http://maka.im/">http://maka.im/</a></li>
<li>一键海报神器：<a target="_blank" rel="noopener" href="https://www.logosc.cn/photo/?utm_source=hao.logosc.cn&amp;utm_medium=referral">https://www.logosc.cn/photo/?utm_source=hao.logosc.cn&amp;utm_medium=referral</a></li>
<li>字由（字体设计）：<a target="_blank" rel="noopener" href="http://www.hellofont.cn/">http://www.hellofont.cn/</a></li>
<li>查字体网站：<a target="_blank" rel="noopener" href="https://fonts.safe.360.cn/">https://fonts.safe.360.cn/</a></li>
<li>爱给网（免费素材下载的网站，包括音效、配乐，3D、视频、游戏，平面、教程）：<a target="_blank" rel="noopener" href="http://www.aigei.com/">http://www.aigei.com/</a></li>
<li>在线视频剪辑：<a target="_blank" rel="noopener" href="https://bilibili.clipchamp.com/editor">https://bilibili.clipchamp.com/editor</a></li>
</ul>
<h2 id="搞文档"><a href="#搞文档" class="headerlink" title="搞文档"></a><strong>搞文档</strong></h2><ul>
<li>即书（在线制作PPT）：<a target="_blank" rel="noopener" href="https://www.keysuper.com/">https://www.keysuper.com/</a></li>
<li>PDF处理：<a target="_blank" rel="noopener" href="https://smallpdf.com/cn">https://smallpdf.com/cn</a></li>
<li>PDF处理：<a target="_blank" rel="noopener" href="https://www.ilovepdf.com/zh-cn">https://www.ilovepdf.com/zh-cn</a></li>
<li>PDF处理：<a target="_blank" rel="noopener" href="https://www.pdfpai.com/">https://www.pdfpai.com/</a></li>
<li>PDF处理：<a target="_blank" rel="noopener" href="https://www.hipdf.cn/">https://www.hipdf.cn/</a></li>
<li>腾讯文档（在线协作编辑和管理文档）：docs.qq.com</li>
<li>ProcessOn（在线协作制作结构图）：<a target="_blank" rel="noopener" href="http://www.processon.com/">www.processon.com</a></li>
<li>iLovePDF（在线转换PDF利器）：<a target="_blank" rel="noopener" href="http://www.ilovepdf.com/">www.ilovepdf.com</a></li>
<li>PPT在线制作：<a target="_blank" rel="noopener" href="https://www.woodo.cn/">https://www.woodo.cn/</a></li>
<li>PDF24工具（pdf处理工具）：<a target="_blank" rel="noopener" href="https://tools.pdf24.org/en">https://tools.pdf24.org/en</a></li>
<li>IMGBOT（在线图片处理）：<a target="_blank" rel="noopener" href="http://www.imgbot.ai/">www.imgbot.ai</a></li>
<li>福昕云编辑（在线编辑PDF）：edit.foxitcloud.cn</li>
<li>TinyPNG（在线压缩图片）：tinypng.com</li>
<li>UZER.ME（在线使用各种大应用，在线使用CAD，MATLAB，Office三件套</li>
</ul>
<p>）：uzer.me</p>
<ul>
<li>优品PPT（模板下载）：<a target="_blank" rel="noopener" href="http://www.ypppt.com/">http://www.ypppt.com/</a></li>
<li>第一PPT（模板下载）：<a target="_blank" rel="noopener" href="http://www.1ppt.com/xiazai/">http://www.1ppt.com/xiazai/</a></li>
<li>三顿PPT导航：sandunppt.com</li>
</ul>
<h2 id="找图片"><a href="#找图片" class="headerlink" title="找图片"></a><strong>找图片</strong></h2><ul>
<li>电脑壁纸：<a target="_blank" rel="noopener" href="http://lcoc.top/bizhi/">http://lcoc.top/bizhi/</a></li>
<li><a target="_blank" rel="noopener" href="https://unsplash.com/">https://unsplash.com/</a></li>
<li><a target="_blank" rel="noopener" href="https://pixabay.com/">https://pixabay.com/</a></li>
<li><a target="_blank" rel="noopener" href="https://www.pexels.com/">https://www.pexels.com/</a></li>
<li><a target="_blank" rel="noopener" href="https://visualhunt.com/">https://visualhunt.com/</a></li>
<li><a target="_blank" rel="noopener" href="https://www.ssyer.com/">https://www.ssyer.com/</a></li>
<li>彼岸图网：<a target="_blank" rel="noopener" href="http://pic.netbian.com/">http://pic.netbian.com/</a></li>
<li>极像素（超高清大图）：<a target="_blank" rel="noopener" href="https://www.sigoo.com/">https://www.sigoo.com/</a></li>
<li>免费版权图片搜索：<a target="_blank" rel="noopener" href="https://www.logosc.cn/so/">https://www.logosc.cn/so/</a></li>
</ul>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/tips/" rel="tag">tips</a></li></ul>

    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-tips/30 种提高工作效率的利器"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/11/11/tips/30%20%E7%A7%8D%E6%8F%90%E9%AB%98%E5%B7%A5%E4%BD%9C%E6%95%88%E7%8E%87%E7%9A%84%E5%88%A9%E5%99%A8/"
    >30 种提高工作效率的利器.md</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/11/11/tips/30%20%E7%A7%8D%E6%8F%90%E9%AB%98%E5%B7%A5%E4%BD%9C%E6%95%88%E7%8E%87%E7%9A%84%E5%88%A9%E5%99%A8/" class="article-date">
  <time datetime="2020-11-10T16:00:00.000Z" itemprop="datePublished">2020-11-11</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/tips/">tips</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h1 id="30-种提高工作效率的利器"><a href="#30-种提高工作效率的利器" class="headerlink" title="30 种提高工作效率的利器"></a>30 种提高工作效率的利器</h1><blockquote>
<p>工欲善其事必先利其器。</p>
<p>我一直都在不断挑选和优化自己的兵器，以追求着最高效率。</p>
<p>此篇分享下我的私家珍藏的各种神兵利器。如果有朋友能推荐更好的，那就不枉此篇。</p>
<p><strong>分为Windows软件和开发工具两类。</strong></p>
</blockquote>
<h2 id=""><a href="#" class="headerlink" title=""></a></h2><h2 id="1、windows软件"><a href="#1、windows软件" class="headerlink" title="1、windows软件"></a><strong>1、windows软件</strong></h2><ul>
<li><h3 id="快速启动：WOX"><a href="#快速启动：WOX" class="headerlink" title="快速启动：WOX"></a><strong>快速启动：WOX</strong></h3></li>
</ul>
<p>快速启动应用+文件搜索+各种实用插件（计算器、翻译、网页快速访问等）。我的最爱，没有它我几乎半残。一开始从用altrun 然后试过Listary ，发现WOX 后，最为顺手，效率提升100%。</p>
<ul>
<li><h3 id="搜索工具：everything"><a href="#搜索工具：everything" class="headerlink" title="搜索工具：everything"></a><strong>搜索工具：everything</strong></h3></li>
</ul>
<p>秒找电脑里的各种文件。与WOX完美集成。</p>
<ul>
<li><h3 id="下载：IDM"><a href="#下载：IDM" class="headerlink" title="下载：IDM"></a><strong>下载：IDM</strong></h3></li>
</ul>
<p>多线程下载HTTP类文件下载利器，杠杠的。Chrome 内的下载都托管给了IDM，可下载百度云离线文件，突破下载速度限制。</p>
<p>做不到的BT 下载，使用迅雷下载或者Aria2 来配合处理即可。</p>
<ul>
<li><h3 id="截图：snipaste"><a href="#截图：snipaste" class="headerlink" title="截图：snipaste"></a><strong>截图：snipaste</strong></h3></li>
</ul>
<p>开源、免费的国产截图神器。给我最大的感受是截图更方便，且比QQ截图工具清晰很多。</p>
<ul>
<li><h3 id="预览工具：QuickLook"><a href="#预览工具：QuickLook" class="headerlink" title="预览工具：QuickLook"></a><strong>预览工具：QuickLook</strong></h3></li>
</ul>
<p>按下空格即可快速预览文件，微软商店内的免费应用。</p>
<p>之前用的seer，发现QuickLook 后，果断抛弃。</p>
<ul>
<li><h3 id="剪切板工具：Ditto"><a href="#剪切板工具：Ditto" class="headerlink" title="剪切板工具：Ditto"></a><strong>剪切板工具：Ditto</strong></h3></li>
</ul>
<p>再也不用担心刚才复制的内容找不到了。</p>
<ul>
<li><h3 id="结构化笔记：workflowy"><a href="#结构化笔记：workflowy" class="headerlink" title="结构化笔记：workflowy"></a><strong>结构化笔记：workflowy</strong></h3></li>
</ul>
<p>Make lists,not war.我常用于记录工作中的各种待办事项。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585324.png" alt="img"></p>
<ul>
<li><h3 id="Markdown写作工具：Typora"><a href="#Markdown写作工具：Typora" class="headerlink" title="Markdown写作工具：Typora"></a><strong>Markdown写作工具：Typora</strong></h3></li>
</ul>
<p>最好用的Markdown写作工具，所见即所得。</p>
<ul>
<li><h3 id="贴图工具：PicGo"><a href="#贴图工具：PicGo" class="headerlink" title="贴图工具：PicGo"></a><strong>贴图工具：PicGo</strong></h3></li>
</ul>
<p>支持多种图床，功能强大。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585338.jpg" alt="img"></p>
<ul>
<li><h3 id="看图工具：2345看图王"><a href="#看图工具：2345看图王" class="headerlink" title="看图工具：2345看图王"></a><strong>看图工具：2345看图王</strong></h3></li>
</ul>
<p>虽然名字土鳖，国产软件，一贯的有流氓行为。但是看图是真好用，我能忍。233333.</p>
<ul>
<li><h3 id="压缩软件：BandZIP"><a href="#压缩软件：BandZIP" class="headerlink" title="压缩软件：BandZIP"></a><strong>压缩软件：BandZIP</strong></h3></li>
<li><h3 id="播放器：Splash"><a href="#播放器：Splash" class="headerlink" title="播放器：Splash"></a><strong>播放器：Splash</strong></h3></li>
<li><h3 id="录屏工具：LICEcap"><a href="#录屏工具：LICEcap" class="headerlink" title="录屏工具：LICEcap"></a><strong>录屏工具：LICEcap</strong></h3></li>
</ul>
<p>比GifCam更好用。</p>
<ul>
<li><h3 id="Chrome插件"><a href="#Chrome插件" class="headerlink" title="Chrome插件"></a><strong>Chrome插件</strong></h3></li>
</ul>
<ol>
<li><p>Surfingkeys</p>
<p>在Chrome上，可以摆脱掉烦人的鼠标了。Vimium 升级版，我的最爱。</p>
</li>
<li><p>Tampermonkey</p>
<p>一千个司机眼中有一千个油猴。</p>
<p>强大的脚本让你可以做很多很爽的事情。比如开车、百度网盘破解直接下载、VIP视频在线解析破解去广告等。</p>
</li>
<li><p>沙拉查词-网页划词翻译</p>
<p>全能网页划词翻译，开放源码、功能丰富、超多词典、清爽快速、支持个性化设置</p>
<p>详细信息删除。</p>
<p>找了很久才找到的划词翻译软件，而且双击Ctrl还可以弹出查询翻译页面。用起来很爽。</p>
</li>
<li><p>掘金</p>
<p>新标签页托管给掘金，快速获得专业内容。掘金已成为一种习惯。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585327.webp" alt="img"></p>
</li>
<li><p>Imagus</p>
<p>鼠标悬浮停留在图片上，自动弹出放大图片，不用再在新链接中打开看大图了。</p>
</li>
<li><p>oneTab</p>
<p>标签页打开太多的时候，占用内存而且怕关掉后回头找不到？oneTab完美解决这个问题。</p>
<p>主要是用来缩减窗口，保存浏览记录。</p>
<p>为了省内存？Chrome越来越吃内存？加内存条才是根本的解决办法。</p>
</li>
<li><p>AutoPagerize</p>
<p>专门需要Google、百度，点击下一页很烦。AutoPagerize让我不再需要点下一页。</p>
</li>
<li><p>谷歌访问助手</p>
<p>如果你只要访问个谷歌或者上谷歌商店的话，不需要突破围墙的话，装这个插件可以满足基本使用了。免费而且速度还行。</p>
<p>在我的酸酸乳被严打封锁期间，我是靠着这个插件熬下来的，且行且珍惜。良民万岁。</p>
</li>
<li><p>Proxy SwitchyOmega</p>
<p>HTTP、SOCKS5代理插件，轻松快捷地管理和切换多个代理设置。用过段时间，挺好用的。</p>
</li>
<li><p>LastPass</p>
<p>省掉很多记密码的烦恼。</p>
</li>
<li><p>Insight.io for Github</p>
<p>IDE like code intelligence and code search for GitHub by Insight.io.</p>
</li>
<li><p>Github内看代码更方便，带高亮、跳转。</p>
<p>GitZip for github</p>
<p>It can make the sub-directories and files of github repository as zip and download it.</p>
<p>不想Clone整个项目，只想下载单个文件或者单个文件夹时，用这个。</p>
</li>
<li><p>Clear Cache</p>
<p>一键清除缓存，可以少点很多步。</p>
</li>
<li><p>User-Agent Switcher for Chrome</p>
<p>Chrome可以转换为别的浏览器进行访问，如IE、Safari、360甚至iOS、 Android等移动浏览器，方便用户进行测试。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585336.webp" alt="img"></p>
</li>
<li><p>Adblock Plus</p>
<p>网页去广告，不用uBlock Origin 的原因是它太强力，有时候把我博客的评论部分都杀掉了。</p>
</li>
<li><p>微博图床</p>
<p>一键将页面中的图片上传到微博，微博是个好图床。我一般用微博图床来拿HTTPS图片。</p>
</li>
<li><p>扩展管理器（Extension Manager）</p>
<p>一键管理所有扩展，快速开启/禁用、批量闪电管理，智能排序，右键卸载、锁定、选项配置，角标提醒，大小布局随心配。快捷、简单、安全。</p>
<p>当插件越来越多的时候，就需要个插件管理器了。这个管理器很方便，颜值不错。</p>
</li>
<li><p>IDM Integration Module</p>
<p>接管Chrome下载，使用IDM下载。一般在安装IDM的时候会自动安装Chrome的扩展。</p>
</li>
<li><p>惠惠购物助手</p>
<p>每逢剁手节的时候，都要打开这个看看历史价。</p>
</li>
<li><p>有道云网页剪报</p>
<p>一键保存网页内容，保存到有道云笔记里，我有时候将这个作为类似书签使用。</p>
</li>
</ol>
<h2 id="2、开发相关"><a href="#2、开发相关" class="headerlink" title="2、开发相关"></a><strong>2、开发相关</strong></h2><ul>
<li><h3 id="IDE：IntelliJ-IDEA"><a href="#IDE：IntelliJ-IDEA" class="headerlink" title="IDE：IntelliJ IDEA"></a><strong>IDE：IntelliJ IDEA</strong></h3></li>
</ul>
<p>用了有些年头了，高效、顺滑。也是因为从IDEA开始，让我意识到工具的重要性，在折腾工具的这条路上越走越远。</p>
<ul>
<li><h3 id="IDEA插件私家珍藏"><a href="#IDEA插件私家珍藏" class="headerlink" title="IDEA插件私家珍藏"></a><strong>IDEA插件私家珍藏</strong></h3></li>
</ul>
<ol>
<li><p>JRebel for IntelliJ</p>
<p>热部署插件，Java WEB 开发必备，节省生命。</p>
</li>
<li><p>Custom Postfix Templates</p>
<p>我的最爱。可以自定义Postfix模板，千言万语，不如一图。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585328.gif" alt="img"></p>
</li>
<li><p>Lombok Plugin</p>
<p>使用注解自动生成代码，码奴解放者。</p>
</li>
<li><p>RestfulToolkit</p>
<p>Java WEB开发必备，再也不用全局搜索RequestMapping了。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585336.gif" alt="img"></p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585337.webp" alt="img"></p>
</li>
<li><p>Translation</p>
<p>翻译插件，很好用。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585329.png" alt="img"></p>
</li>
<li><p>Grep Console</p>
<p>高亮log不同级别日志，看日志的时候一目了然。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585327.webp" alt="img"></p>
</li>
<li><p>GenerateSerialVersionUID</p>
<p>Alt + Insert 生成serialVersionUID</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585173.gif" alt="img"></p>
</li>
<li><p>Git Flow Integration</p>
<p>Git Flow插件，与IDEA集成。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585325.webp" alt="img"></p>
<p><img src="http://iubest.gitee.io/pic/640-1601368016832.webp" alt="img"></p>
</li>
<li><p>GsonFormat</p>
<p>JSON报文 –&gt; Java POJO 快速转换。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585326.gif" alt="img"></p>
</li>
<li><p>Material Theme UI</p>
<p>UI主题，有三款配色，看个人喜好。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601368031841.webp" alt="img"></p>
</li>
<li><p>String Manipulation</p>
<p>字符串格式风格快捷转换：大小写、驼峰、连接串等。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585324.gif" alt="img"></p>
</li>
<li><p>Alibaba Java Coding Guidelines</p>
<p>阿里巴巴Java开发规约扫描插件。</p>
</li>
<li><p>FindBugs</p>
<p>找到代码中潜在的问题。</p>
</li>
<li><p>Rainbow Brackets</p>
<p>彩虹括号。自动给代码块内花括号和括号加色，让视野更加注意在代码上。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585338.webp" alt="img"></p>
</li>
<li><p>Maven Helper</p>
<p>Maven插件，安装后可查看依赖以及冲突，一目了然。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585326.webp" alt="img"></p>
</li>
</ol>
<ul>
<li><h3 id="文本编辑器：Sublime"><a href="#文本编辑器：Sublime" class="headerlink" title="文本编辑器：Sublime"></a><strong>文本编辑器：Sublime</strong></h3></li>
</ul>
<p>对比Atom，Sublime主要是打开速度更快，感觉更清爽。</p>
<ul>
<li><h3 id="数据库客户端：DataGrip"><a href="#数据库客户端：DataGrip" class="headerlink" title="数据库客户端：DataGrip"></a><strong>数据库客户端：DataGrip</strong></h3></li>
</ul>
<p>一个客户端全搞定主流数据库。不用再装Navicat、plsql了。</p>
<p>ps:DataGrip其实只是IDEA里一个集成功能，被单独抽离出来成了一个独立产品。</p>
<ul>
<li><h3 id="SSH客户端：MobaXterm"><a href="#SSH客户端：MobaXterm" class="headerlink" title="SSH客户端：MobaXterm"></a><strong>SSH客户端：MobaXterm</strong></h3></li>
</ul>
<p>集成SSH、SFTP、FTP等，一个全搞定。还可分屏等功能，好用。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585337.webp" alt="img"></p>
<ul>
<li><h3 id="终端工具：Cmder"><a href="#终端工具：Cmder" class="headerlink" title="终端工具：Cmder"></a><strong>终端工具：Cmder</strong></h3></li>
</ul>
<p>丢弃掉Windows自带cmd窗口吧。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601007585328.webp" alt="img"></p>
<ul>
<li><h3 id="API工具：Postman"><a href="#API工具：Postman" class="headerlink" title="API工具：Postman"></a><strong>API工具：Postman</strong></h3></li>
</ul>
<p>强大的API调试、Http请求的工具 。可自动同步个人请求记录。</p>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/tips/" rel="tag">tips</a></li></ul>

    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-tips/Java 应用最常见的3个问题排查思路"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/11/11/tips/Java%20%E5%BA%94%E7%94%A8%E6%9C%80%E5%B8%B8%E8%A7%81%E7%9A%843%E4%B8%AA%E9%97%AE%E9%A2%98%E6%8E%92%E6%9F%A5%E6%80%9D%E8%B7%AF/"
    >Java 应用最常见的3个问题排查思路.md</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/11/11/tips/Java%20%E5%BA%94%E7%94%A8%E6%9C%80%E5%B8%B8%E8%A7%81%E7%9A%843%E4%B8%AA%E9%97%AE%E9%A2%98%E6%8E%92%E6%9F%A5%E6%80%9D%E8%B7%AF/" class="article-date">
  <time datetime="2020-11-10T16:00:00.000Z" itemprop="datePublished">2020-11-11</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/tips/">tips</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h1 id="Java-应用最常见的3个问题排查思路"><a href="#Java-应用最常见的3个问题排查思路" class="headerlink" title="Java 应用最常见的3个问题排查思路"></a>Java 应用最常见的3个问题排查思路</h1><p>本文总结了一些常见的线上应急现象和对应排查步骤和工具。分享的主要目的是想让对线上问题接触少的同学有个预先认知，免得在遇到实际问题时手忙脚乱。毕竟作者自己也是从手忙脚乱时走过来的。</p>
<p>只不过这里先提示一下。在线上应急过程中要记住，只有一个总体目标：<strong>尽快恢复服务，消除影响</strong>。不管处于应急的哪个阶段，我们首先必须想到的是恢复问题，恢复问题不一定能够定位问题，也不一定有完美的解决方案，也许是通过经验判断，也许是预设开关等，但都可能让我们达到快速恢复的目的，然后<strong>保留部分现场，再去定位问题、解决问题和复盘</strong>。</p>
<p>在大多数情况下，我们都是先优先恢复服务，保留下当时的异常信息（内存dump、线程dump、gc log等等，在紧急情况下甚至可以不用保留，等到事后去复现），等到服务正常，再去复盘问题。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601172415053.webp" alt="img"></p>
<p>好，现在让我们进入正题吧。</p>
<h2 id=""><a href="#" class="headerlink" title=""></a></h2><h2 id="常见现象1：CPU-利用率高-飙升"><a href="#常见现象1：CPU-利用率高-飙升" class="headerlink" title="常见现象1：CPU 利用率高/飙升"></a><strong>常见现象1：CPU 利用率高/飙升</strong></h2><p>**<br>**</p>
<h3 id="场景预设："><a href="#场景预设：" class="headerlink" title="场景预设："></a>场景预设：</h3><p>监控系统突然告警，提示服务器负载异常。</p>
<h3 id="预先说明："><a href="#预先说明：" class="headerlink" title="预先说明："></a>预先说明：</h3><p>CPU飙升只是一种现象，其中具体的问题可能有很多种，这里只是借这个现象切入。</p>
<blockquote>
<p>注：CPU使用率是衡量系统繁忙程度的重要指标。但是<strong>CPU使用率的安全阈值是相对的，取决于你的系统的IO密集型还是计算密集型</strong>。一般计算密集型应用CPU使用率偏高load偏低，IO密集型相反。</p>
</blockquote>
<h3 id="常见原因："><a href="#常见原因：" class="headerlink" title="常见原因："></a>常见原因：</h3><ul>
<li>频繁 gc</li>
<li>死循环、线程阻塞、io wait…etc</li>
</ul>
<h3 id="模拟"><a href="#模拟" class="headerlink" title="模拟"></a>模拟</h3><p>这里为了演示，用一个最简单的死循环来模拟CPU飙升的场景，下面是模拟代码，</p>
<p>在一个最简单的SpringBoot Web 项目中增加<code>CpuReaper</code>这个类，</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">&#x2F;**</span><br><span class="line"> * 模拟 cpu 飙升场景</span><br><span class="line"> * @author Richard_yyf</span><br><span class="line"> *&#x2F;</span><br><span class="line">@Component</span><br><span class="line">public class CpuReaper &#123;</span><br><span class="line"></span><br><span class="line">    @PostConstruct</span><br><span class="line">    public void cpuReaper() &#123;</span><br><span class="line">        int num &#x3D; 0;</span><br><span class="line">        long start &#x3D; System.currentTimeMillis() &#x2F; 1000;</span><br><span class="line">        while (true) &#123;</span><br><span class="line">            num &#x3D; num + 1;</span><br><span class="line">            if (num &#x3D;&#x3D; Integer.MAX_VALUE) &#123;</span><br><span class="line">                System.out.println(&quot;reset&quot;);</span><br><span class="line">                num &#x3D; 0;</span><br><span class="line">            &#125;</span><br><span class="line">            if ((System.currentTimeMillis() &#x2F; 1000) - start &gt; 1000) &#123;</span><br><span class="line">                return;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>打包成jar之后，在服务器上运行。<code>java -jar cpu-reaper.jar &amp;</code></p>
<h3 id="第一步：定位出问题的线程"><a href="#第一步：定位出问题的线程" class="headerlink" title="第一步：定位出问题的线程"></a>第一步：定位出问题的线程</h3><h4 id="方法-a-传统的方法"><a href="#方法-a-传统的方法" class="headerlink" title="方法 a: 传统的方法"></a>方法 a: 传统的方法</h4><ol>
<li><p><code>top</code> 定位CPU 最高的进程</p>
<p>执行<code>top</code>命令，查看所有进程占系统CPU的排序，定位是哪个进程搞的鬼。在本例中就是咱们的java进程。PID那一列就是进程号。(对指示符含义不清楚的见【附录】)</p>
<p><img src="http://iubest.gitee.io/pic/640-1601172415058.webp" alt="img"></p>
</li>
<li><p><code>top -Hp pid</code> 定位使用 CPU 最高的线程</p>
<p><img src="http://iubest.gitee.io/pic/640-1601172415056.webp" alt="img"></p>
</li>
<li><p><code>printf &#39;0x%x&#39; tid</code> 线程 id 转化 16 进制</p>
</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&gt; printf &#39;0x%x&#39; 12817&gt; 0x3211</span><br></pre></td></tr></table></figure>

<ol>
<li><code>jstack pid | grep tid</code> 找到线程堆栈</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&gt; jstack 12816 | grep 0x3211 -A 30</span><br></pre></td></tr></table></figure>

<p><img src="http://iubest.gitee.io/pic/640-1601172415288.webp" alt="img"></p>
<h4 id="方法-b-show-busy-java-threads"><a href="#方法-b-show-busy-java-threads" class="headerlink" title="方法 b: show-busy-java-threads"></a>方法 b: show-busy-java-threads</h4><p>这个脚本来自于github上一个开源项目，项目提供了很多有用的脚本，<code>show-busy-java-threads</code>就是其中的一个。使用这个脚本，可以直接简化方法A中的繁琐步骤。如下，</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&gt; wget --no-check-certificate https:&#x2F;&#x2F;raw.github.com&#x2F;oldratlee&#x2F;useful-scripts&#x2F;release-2.x&#x2F;bin&#x2F;show-busy-java-threads</span><br><span class="line">&gt; chmod +x show-busy-java-threads</span><br><span class="line">&gt; .&#x2F;show-busy-java-threads</span><br></pre></td></tr></table></figure>

<p><img src="http://iubest.gitee.io/pic/640-1601172415287.webp" alt="img"></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">show-busy-java-threads</span><br><span class="line"># 从所有运行的Java进程中找出最消耗CPU的线程（缺省5个），打印出其线程栈</span><br><span class="line"># 缺省会自动从所有的Java进程中找出最消耗CPU的线程，这样用更方便</span><br><span class="line"># 当然你可以手动指定要分析的Java进程Id，以保证只会显示你关心的那个Java进程的信息</span><br><span class="line">show-busy-java-threads -p &lt;指定的Java进程Id&gt;</span><br><span class="line"></span><br><span class="line">show-busy-java-threads -c &lt;要显示的线程栈数&gt;</span><br></pre></td></tr></table></figure>

<h4 id="方法-c-arthas-thread"><a href="#方法-c-arthas-thread" class="headerlink" title="方法 c: arthas thread"></a>方法 c: arthas <code>thread</code></h4><p>阿里开源的arthas现在已经几乎包揽了我们线上排查问题的工作，提供了一个很完整的工具集。在这个场景中，也只需要一个<code>thread -n</code>命令即可。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&gt; curl -O https:&#x2F;&#x2F;arthas.gitee.io&#x2F;arthas-boot.jar # 下载</span><br></pre></td></tr></table></figure>

<p><img src="http://iubest.gitee.io/pic/640-1601172415055.webp" alt="img"></p>
<blockquote>
<p>要注意的是，arthas的cpu占比，和前面两种cpu占比统计方式不同。前面两种针对的是Java进程启动开始到现在的cpu占比情况，arthas这种是一段采样间隔内，当前JVM里各个线程所占用的cpu时间占总cpu时间的百分比。</p>
<p>具体见官网：<a target="_blank" rel="noopener" href="https://alibaba.github.io/arthas/thread.html">https://alibaba.github.io/arthas/thread.html</a></p>
</blockquote>
<h3 id="后续"><a href="#后续" class="headerlink" title="后续"></a>后续</h3><p>通过第一步，找出有问题的代码之后，观察到线程栈之后。我们<strong>就要根据具体问题来具体分析</strong>。这里举几个例子。</p>
<h4 id="情况一：发现使用CPU最高的都是GC-线程。"><a href="#情况一：发现使用CPU最高的都是GC-线程。" class="headerlink" title="情况一：发现使用CPU最高的都是GC 线程。"></a>情况一：发现使用CPU最高的都是GC 线程。</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">GC task thread#0 (ParallelGC)&quot; os_prio&#x3D;0 tid&#x3D;0x00007fd99001f800 nid&#x3D;0x779 runnableGC task thread#1 (ParallelGC)&quot; os_prio&#x3D;0 tid&#x3D;0x00007fd990021800 nid&#x3D;0x77a runnable GC task thread#2 (ParallelGC)&quot; os_prio&#x3D;0 tid&#x3D;0x00007fd990023000 nid&#x3D;0x77b runnable GC task thread#3 (ParallelGC)&quot; os_prio&#x3D;0 tid&#x3D;0x00007fd990025000 nid&#x3D;0x77c runnabl</span><br></pre></td></tr></table></figure>

<p>gc 排查的内容较多，所以我决定在后面单独列一节讲述。</p>
<h4 id="情况二：发现使用CPU最高的是业务线程"><a href="#情况二：发现使用CPU最高的是业务线程" class="headerlink" title="情况二：发现使用CPU最高的是业务线程"></a>情况二：发现使用CPU最高的是业务线程</h4><ul>
<li><p>io wait</p>
</li>
<li><ul>
<li>比如此例中，就是因为磁盘空间不够导致的io阻塞</li>
</ul>
</li>
<li><p>等待内核态锁，如 synchronized</p>
</li>
<li><ul>
<li><code>jstack -l pid | grep BLOCKED</code> 查看阻塞态线程堆栈</li>
<li>dump 线程栈，分析线程持锁情况。</li>
<li>arthas提供了<code>thread -b</code>，可以找出当前阻塞其他线程的线程。针对 synchronized 情况</li>
</ul>
</li>
</ul>
<h2 id="-1"><a href="#-1" class="headerlink" title=""></a></h2><h2 id="常见现象2：频繁-GC"><a href="#常见现象2：频繁-GC" class="headerlink" title="常见现象2：频繁 GC"></a><strong>常见现象2：频繁 GC</strong></h2><p>**<br>**</p>
<h3 id="1-回顾GC流程"><a href="#1-回顾GC流程" class="headerlink" title="1. 回顾GC流程"></a>1. 回顾GC流程</h3><p>在了解下面内容之前，请先花点时间回顾一下GC的整个流程。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601172415057.webp" alt="img"></p>
<hr>
<p>接前面的内容，这个情况下，我们自然而然想到去查看gc 的具体情况。</p>
<ul>
<li>方法a : 查看gc 日志</li>
<li>方法b : <code>jstat -gcutil 进程号 统计间隔毫秒 统计次数（缺省代表一致统计</code></li>
<li>方法c : 如果所在公司有对应用进行监控的组件当然更方便（比如Prometheus + Grafana）</li>
</ul>
<p>这里对开启 gc log 进行补充说明。一个常常被讨论的问题（惯性思维）是在生产环境中GC日志是否应该开启。因为它所产生的开销通常都非常有限，因此我的答案是需要<strong>开启</strong>。但并不一定在启动JVM时就必须指定GC日志参数。</p>
<blockquote>
<p>HotSpot JVM有一类特别的参数叫做可管理的参数。对于这些参数，可以在运行时修改他们的值。我们这里所讨论的所有参数以及以“PrintGC”开头的参数都是可管理的参数。这样在任何时候我们都可以开启或是关闭GC日志。比如我们可以使用JDK自带的jinfo工具来设置这些参数，或者是通过JMX客户端调用<code>HotSpotDiagnostic MXBean的</code>setVMOption方法来设置这些参数。</p>
<p>这里再次大赞arthas❤️，它提供的<code>vmoption</code>命令可以直接查看，更新VM诊断相关的参数。</p>
</blockquote>
<p>获取到gc日志之后，可以上传到GC easy帮助分析，得到可视化的图表分析结果。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601172415289.webp" alt="img"></p>
<p><img src="http://iubest.gitee.io/pic/640-1601172448912.webp" alt="img"></p>
<h3 id="2-GC-原因及定位"><a href="#2-GC-原因及定位" class="headerlink" title="2. GC 原因及定位"></a>2. GC 原因及定位</h3><p><strong>prommotion failed</strong></p>
<p>从S区晋升的对象在老年代也放不下导致 FullGC（fgc 回收无效则抛 OOM）。</p>
<p>可能原因：</p>
<ul>
<li><p>survivor 区太小，对象过早进入老年代</p>
<p>查看 SurvivorRatio 参数</p>
</li>
<li><p>大对象分配，没有足够的内存</p>
<p>dump 堆，profiler/MAT 分析对象占用情况</p>
</li>
<li><p>old 区存在大量对象</p>
<p>dump 堆，profiler/MAT 分析对象占用情况</p>
</li>
</ul>
<p>你也可以从full GC 的效果来推断问题，正常情况下，一次full GC应该会回收大量内存，所以 <strong>正常的堆内存曲线应该是呈锯齿形</strong>。如果你发现full gc 之后堆内存几乎没有下降，那么可以推断：**堆中有大量不能回收的对象且在不停膨胀，使堆的使用占比超过full GC的触发阈值，但又回收不掉，导致full GC一直执行。换句话来说，可能是内存泄露了。</p>
<p>一般来说，GC相关的异常推断都需要涉及到<strong>内存分析</strong>，使用<code>jmap</code>之类的工具dump出内存快照（或者 Arthas的<code>heapdump</code>）命令，然后使用MAT、JProfiler、JVisualVM等可视化内存分析工具。</p>
<p>至于内存分析之后的步骤，就需要小伙伴们根据具体问题具体分析啦。</p>
<h2 id="-2"><a href="#-2" class="headerlink" title=""></a></h2><h2 id="常见现象3：线程池异常"><a href="#常见现象3：线程池异常" class="headerlink" title="常见现象3：线程池异常"></a><strong>常见现象3：线程池异常</strong></h2><h3 id="场景预设：-1"><a href="#场景预设：-1" class="headerlink" title="场景预设："></a>场景预设：</h3><p>业务监控突然告警，或者外部反馈提示大量请求执行失败。</p>
<h3 id="异常说明："><a href="#异常说明：" class="headerlink" title="异常说明："></a>异常说明：</h3><p>Java 线程池以有界队列的线程池为例，当新任务提交时，如果运行的线程少于 corePoolSize，则创建新线程来处理请求。如果正在运行的线程数等于 corePoolSize 时，则新任务被添加到队列中，直到队列满。当队列满了后，会继续开辟新线程来处理任务，但不超过 maximumPoolSize。当任务队列满了并且已开辟了最大线程数，此时又来了新任务，ThreadPoolExecutor 会拒绝服务。</p>
<h3 id="常见问题和原因"><a href="#常见问题和原因" class="headerlink" title="常见问题和原因"></a>常见问题和原因</h3><p>这种线程池异常，一般可以通过开发查看日志查出原因，有以下几种原因：</p>
<ol>
<li><p>下游服务 响应时间（RT）过长</p>
<p>这种情况有可能是因为下游服务异常导致的，作为消费者我们要设置合适的超时时间和熔断降级机制。</p>
<p>另外针对这种情况，一般都要有对应的监控机制：比如日志监控、metrics监控告警等，不要等到目标用户感觉到异常，从外部反映进来问题才去看日志查。</p>
</li>
<li><p>数据库慢 sql 或者数据库死锁</p>
</li>
</ol>
<p>查看日志中相关的关键词。</p>
<ol>
<li><p>Java 代码死锁</p>
<p><code>jstack –l pid | grep -i –E &#39;BLOCKED | deadlock&#39;</code></p>
</li>
</ol>
<h2 id="-3"><a href="#-3" class="headerlink" title=""></a></h2><h2 id="常见问题恢复"><a href="#常见问题恢复" class="headerlink" title="常见问题恢复"></a><strong>常见问题恢复</strong></h2><p>**<br>**</p>
<p>对于上文提到的一些问题，这里总结了一些恢复的方法。</p>
<p><img src="http://iubest.gitee.io/pic/640-1601172414643.webp" alt="img"></p>
<p>- END -</p>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/tips/" rel="tag">tips</a></li></ul>

    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-tips/Tmux常用操作"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/11/11/tips/Tmux%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/"
    >Tmux常用操作.md</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/11/11/tips/Tmux%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/" class="article-date">
  <time datetime="2020-11-10T16:00:00.000Z" itemprop="datePublished">2020-11-11</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/tips/">tips</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h1 id="Tmux常用操作"><a href="#Tmux常用操作" class="headerlink" title="Tmux常用操作"></a>Tmux常用操作</h1><h2 id="tmux是什么"><a href="#tmux是什么" class="headerlink" title="tmux是什么"></a>tmux是什么</h2><p>tmux（terminal multiplexer）是Linux上的终端复用神器，可从一个屏幕上管理多个终端（准确说是伪终端）。使用该工具，用户可以连接或断开会话，而保持终端在后台运行。类似的工具还有screen，个人对这二者的使用感受是，用过tmux就再也不想用screen了。</p>
<h2 id="tmux基本操作"><a href="#tmux基本操作" class="headerlink" title="tmux基本操作"></a>tmux基本操作</h2><p>基本的操作无非就是对会话、窗口、窗格进行管理，包括创建、关闭、重命名、连接、分离、选择等等。</p>
<p>一般使用命令和快捷键进行操作，可在系统shell终端和tmux命令模式（类似vim的命令模式）下使用命令，或者在tmux终端使用快捷键。</p>
<p>tmux默认的快捷键前缀是<strong>Ctrl+b</strong>(下文用<strong>prefix</strong>指代)，按下前缀组合键后松开，再按下命令键进行快捷操作，比如使用<strong>prefix d</strong>分离会话（应该写作<strong>prefix d</strong>而不是<strong>prefix+d，</strong>因为<strong>d</strong>键不需要与<strong>prefix</strong>同时按下）。</p>
<p>快捷键可以自定义，比如将前缀改为<strong>Ctrl+a</strong>，但需要保留shell默认的<strong>Ctrl+a</strong>快捷键，按如下所示修改~/.tmux.conf文件：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">set-option -g prefix C-a</span><br><span class="line">2 unbind-key C-b</span><br><span class="line">3 bind-key C-a send-prefix</span><br><span class="line">4 bind-key R source-file ~&#x2F;.tmux.conf \; display-message &quot;~&#x2F;.tmux.conf reloaded.&quot;</span><br></pre></td></tr></table></figure>

<p>现在已将原先的<strong>Ctrl+a</strong>用<strong>prefix Ctrl+a</strong>取代，即需要按两次<strong>Ctrl+a</strong>生效。</p>
<h3 id="会话管理"><a href="#会话管理" class="headerlink" title="会话管理　"></a>会话管理　</h3><p><strong>常用命令</strong></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">tmux new　　创建默认名称的会话（在tmux命令模式使用new命令可实现同样的功能，其他命令同理，后文不再列出tmux终端命令）</span><br><span class="line"></span><br><span class="line">tmux new -s mysession　　创建名为mysession的会话</span><br><span class="line"></span><br><span class="line">tmux ls　　显示会话列表</span><br><span class="line"></span><br><span class="line">tmux a　　连接上一个会话</span><br><span class="line"></span><br><span class="line">tmux a -t mysession　　连接指定会话</span><br><span class="line"></span><br><span class="line">tmux rename -t s1 s2　　重命名会话s1为s2</span><br><span class="line"></span><br><span class="line">tmux kill-session　　关闭上次打开的会话</span><br><span class="line"></span><br><span class="line">tmux kill-session -t s1　　关闭会话s1</span><br><span class="line"></span><br><span class="line">tmux kill-session -a -t s1　　关闭除s1外的所有会话</span><br><span class="line"></span><br><span class="line">tmux kill-server　　关闭所有会话</span><br></pre></td></tr></table></figure>

<p><strong>常用快捷键</strong></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">prefix s　　列出会话，可进行切换</span><br><span class="line"></span><br><span class="line">prefix $　　重命名会话</span><br><span class="line"></span><br><span class="line">prefix d　　分离当前会话</span><br><span class="line"></span><br><span class="line">prefix D　　分离指定会话</span><br></pre></td></tr></table></figure>

<h3 id="窗口管理"><a href="#窗口管理" class="headerlink" title="窗口管理"></a>窗口管理</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">prefix c　　创建一个新窗口</span><br><span class="line"></span><br><span class="line">prefix ,　　重命名当前窗口</span><br><span class="line"></span><br><span class="line">prefix w　　列出所有窗口，可进行切换</span><br><span class="line"></span><br><span class="line">prefix n　　进入下一个窗口</span><br><span class="line"></span><br><span class="line">prefix p　　进入上一个窗口</span><br><span class="line"></span><br><span class="line">prefix l　　进入之前操作的窗口</span><br><span class="line"></span><br><span class="line">prefix 0~9　　选择编号0~9对应的窗口</span><br><span class="line"></span><br><span class="line">prefix .　　修改当前窗口索引编号</span><br><span class="line"></span><br><span class="line">prefix &#39;　　切换至指定编号（可大于9）的窗口</span><br><span class="line"></span><br><span class="line">prefix f　　根据显示的内容搜索窗格</span><br><span class="line"></span><br><span class="line">prefix &amp;　　关闭当前窗口</span><br></pre></td></tr></table></figure>

<h3 id="窗格管理"><a href="#窗格管理" class="headerlink" title="窗格管理"></a><strong>窗格管理</strong></h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">prefix %　　水平方向创建窗格</span><br><span class="line"></span><br><span class="line">prefix &quot;　　垂直方向创建窗格</span><br><span class="line"></span><br><span class="line">prefix Up|Down|Left|Right　　根据箭头方向切换窗格</span><br><span class="line"></span><br><span class="line">prefix q　　显示窗格编号</span><br><span class="line"></span><br><span class="line">prefix o　　顺时针切换窗格</span><br><span class="line"></span><br><span class="line">prefix &#125;　　与下一个窗格交换位置</span><br><span class="line"></span><br><span class="line">prefix &#123;　　与上一个窗格交换位置</span><br><span class="line"></span><br><span class="line">prefix x　　关闭当前窗格</span><br><span class="line"></span><br><span class="line">prefix space(空格键)　　重新排列当前窗口下的所有窗格</span><br><span class="line"></span><br><span class="line">prefix !　　将当前窗格置于新窗口</span><br><span class="line"></span><br><span class="line">prefix Ctrl+o　　逆时针旋转当前窗口的窗格</span><br><span class="line"></span><br><span class="line">prefix t　　在当前窗格显示时间</span><br><span class="line"></span><br><span class="line">prefix z　　放大当前窗格(再次按下将还原)</span><br><span class="line"></span><br><span class="line">prefix i　　显示当前窗格信息</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h3 id="其他命令"><a href="#其他命令" class="headerlink" title="其他命令"></a><strong>其他命令</strong></h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">tmux list-key　　列出所有绑定的键，等同于prefix ?</span><br><span class="line"></span><br><span class="line">tmux list-command　　列出所有命令</span><br></pre></td></tr></table></figure>

<p>ist-command　　列出所有命令</p>
<pre><code></code></pre>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/tips/" rel="tag">tips</a></li></ul>

    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-tips/git仓库清理缓存"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/11/11/tips/git%E4%BB%93%E5%BA%93%E6%B8%85%E7%90%86%E7%BC%93%E5%AD%98/"
    >git仓库清理缓存.md</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/11/11/tips/git%E4%BB%93%E5%BA%93%E6%B8%85%E7%90%86%E7%BC%93%E5%AD%98/" class="article-date">
  <time datetime="2020-11-10T16:00:00.000Z" itemprop="datePublished">2020-11-11</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/tips/">tips</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h1 id="git仓库清理缓存"><a href="#git仓库清理缓存" class="headerlink" title="git仓库清理缓存"></a>git仓库清理缓存</h1><p>码云平台目前对仓库的配额如下：</p>
<table>
<thead>
<tr>
<th>套餐</th>
<th>免费版</th>
<th>基础版</th>
<th>标准版</th>
<th>高级版</th>
<th>尊享版</th>
</tr>
</thead>
<tbody><tr>
<td>单仓库</td>
<td>最大 500 MB</td>
<td>最大 1 GB</td>
<td>最大 1 GB</td>
<td>最大 2 GB</td>
<td>最大 3 GB</td>
</tr>
<tr>
<td>单文件</td>
<td>最大 50 MB</td>
<td>最大 100 MB</td>
<td>最大 100 MB</td>
<td>最大 200 MB</td>
<td>最大 300 MB</td>
</tr>
</tbody></table>
<p>如用户在使用过程中不小心将较大的二进制文件加入仓库，那么仓库大小很快就会超过规定的配额，用户可以通过升级到对应的套餐配额或对仓库进行历史改写瘦身，来解除系统对仓库推拉服务的锁定。</p>
<ul>
<li>套餐升级可访问：<a target="_blank" rel="noopener" href="https://gitee.com/enterprises">https://gitee.com/enterprises</a> 了解</li>
<li>仓库瘦身方案见下方：</li>
</ul>
<h3 id="查看存储库中的大文件"><a href="#查看存储库中的大文件" class="headerlink" title="查看存储库中的大文件"></a>查看存储库中的大文件</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git rev-list --objects --all | grep -E &#96;git verify-pack -v .git&#x2F;objects&#x2F;pack&#x2F;*.idx | sort -k 3 -n | tail -10 | awk &#39;&#123;print$1&#125;&#39; | sed &#39;:a;N;$!ba;s&#x2F;\n&#x2F;|&#x2F;g&#39;&#96;</span><br></pre></td></tr></table></figure>

<p>或</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git rev-list --objects --all | grep &quot;$(git verify-pack -v .git&#x2F;objects&#x2F;pack&#x2F;*.idx | sort -k 3 -n | tail -15 | awk &#39;&#123;print$1&#125;&#39;)&quot;</span><br></pre></td></tr></table></figure>

<h3 id="改写历史，去除大文件"><a href="#改写历史，去除大文件" class="headerlink" title="改写历史，去除大文件"></a>改写历史，去除大文件</h3><blockquote>
<p>注意：下方命令中的 <code>path/to/large/files</code> 是大文件所在的路径，千万不要弄错！</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git filter-branch --tree-filter &#39;rm -f path&#x2F;to&#x2F;large&#x2F;files&#39; --tag-name-filter cat -- --all</span><br><span class="line">git push origin --tags --force</span><br><span class="line">git push origin --all --force</span><br></pre></td></tr></table></figure>

<p>如果在 <code>git filter-branch</code> 操作过程中遇到如下提示，需要在 <code>git filter-branch</code> 后面加上参数 <code>-f</code></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Cannot create a new backup.</span><br><span class="line">A previous backup already exists in refs&#x2F;original&#x2F;</span><br><span class="line">Force overwriting the backup with -f</span><br></pre></td></tr></table></figure>

<p>并告知所有组员，push 代码前需要 pull rebase，而不是 merge，否则会从该组员的本地仓库再次引入到远程库中，导致仓库在此被码云系统屏蔽。</p>
<h3 id="其他参考"><a href="#其他参考" class="headerlink" title="其他参考"></a>其他参考</h3><p>清理和回收空间<br>经过一段时间之后，您确信git filter-branch没有意外的副作用，您可以使用以下命令强制解除对本地存储库中的所有对象的引用和垃圾回收(GC)。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">#git for-each-ref --format&#x3D;&#39;delete %(refname)&#39; refs&#x2F;original | git update-ref --stdin</span><br><span class="line">rm -rf .git&#x2F;refs&#x2F;original&#x2F;</span><br><span class="line">git reflog expire --expire&#x3D;now --all</span><br><span class="line">git gc --prune&#x3D;now</span><br><span class="line">git push origin  --force --tags</span><br><span class="line">git push origin  --all --force</span><br><span class="line"></span><br><span class="line">#Counting objects: 2437, done.</span><br><span class="line">#Delta compression using up to 4 threads.</span><br><span class="line">#Compressing objects: 100% (1378&#x2F;1378), done.</span><br><span class="line">#Writing objects: 100% (2437&#x2F;2437), done.</span><br><span class="line">#Total 2437 (delta 1461), reused 1802 (delta 1048)</span><br></pre></td></tr></table></figure>
<p>您还可以通过将过滤后的历史推入一个新的或空的存储库，然后从GitHub创建一个新的克隆来实现这一点。</p>
<h3 id="清空所有缓存的方法"><a href="#清空所有缓存的方法" class="headerlink" title="清空所有缓存的方法"></a>清空所有缓存的方法</h3><p>有些时候，git 仓库累积了太多无用的历史更改，导致 clone 文件过大。如果确定历史更改没有意义，可以采用下述方法清空历史，</p>
<ol>
<li>先 clone 项目到本地目录 (以名为 mylearning 的仓库为例)</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git clone git@gitee.com:badboycoming&#x2F;mylearning.git</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>进入 mylearning 仓库，拉一个分支，比如名为 latest_branch</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git checkout --orphan latest_branch</span><br></pre></td></tr></table></figure>

<ol start="3">
<li>添加所有文件到上述分支 (<strong>Optional</strong>)</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git add -A</span><br></pre></td></tr></table></figure>

<ol start="4">
<li>提交一次</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git commit -am &quot;Initial commit.&quot;</span><br></pre></td></tr></table></figure>

<ol start="5">
<li>删除 master 分支</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git branch -D master</span><br></pre></td></tr></table></figure>

<ol start="6">
<li>更改当前分支为 master 分支</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git branch -m master</span><br></pre></td></tr></table></figure>

<ol start="7">
<li>将本地所有更改 push 到远程仓库</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git push -f origin master</span><br></pre></td></tr></table></figure>

<ol start="8">
<li>关联本地 master 到远程 master</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git branch --set-upstream-to&#x3D;origin&#x2F;master</span><br></pre></td></tr></table></figure>

<p>注意：对 gitee 用户，因为 gitee 目前限制单个仓库大小为 1024 MB，清除完历史记录后，还要去项目主页 Settings 下做一下 Git GC.</p>
<p>完。</p>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/tips/" rel="tag">tips</a></li></ul>

    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-tips/优质网站收集"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/11/11/tips/%E4%BC%98%E8%B4%A8%E7%BD%91%E7%AB%99%E6%94%B6%E9%9B%86/"
    >优质网站收集.md</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/11/11/tips/%E4%BC%98%E8%B4%A8%E7%BD%91%E7%AB%99%E6%94%B6%E9%9B%86/" class="article-date">
  <time datetime="2020-11-10T16:00:00.000Z" itemprop="datePublished">2020-11-11</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/tips/">tips</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h1 id="优质网站收集"><a href="#优质网站收集" class="headerlink" title="优质网站收集"></a>优质网站收集</h1><p><a target="_blank" rel="noopener" href="https://panjiachen.github.io/awesome-bookmarks/">一位大佬的收藏夹</a></p>
<p><a target="_blank" rel="noopener" href="https://maliquankai.com/designnav/">码力全开资源库</a> 很全很强大，独立开发者/设计干货/优质利器/工具资源…</p> 
      <a class="article-more-link" href="/2020/11/11/tips/%E4%BC%98%E8%B4%A8%E7%BD%91%E7%AB%99%E6%94%B6%E9%9B%86/"
        >阅读更多...</a
      >
       
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/tips/" rel="tag">tips</a></li></ul>

    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-tips/对比测评7大前端可视化布局拖拽的工具"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/11/11/tips/%E5%AF%B9%E6%AF%94%E6%B5%8B%E8%AF%847%E5%A4%A7%E5%89%8D%E7%AB%AF%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B8%83%E5%B1%80%E6%8B%96%E6%8B%BD%E7%9A%84%E5%B7%A5%E5%85%B7/"
    >对比测评7大前端可视化布局拖拽的工具.md</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/11/11/tips/%E5%AF%B9%E6%AF%94%E6%B5%8B%E8%AF%847%E5%A4%A7%E5%89%8D%E7%AB%AF%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B8%83%E5%B1%80%E6%8B%96%E6%8B%BD%E7%9A%84%E5%B7%A5%E5%85%B7/" class="article-date">
  <time datetime="2020-11-10T16:00:00.000Z" itemprop="datePublished">2020-11-11</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/tips/">tips</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h1 id="对比测评7大前端可视化布局拖拽的工具"><a href="#对比测评7大前端可视化布局拖拽的工具" class="headerlink" title="对比测评7大前端可视化布局拖拽的工具"></a>对比测评7大前端可视化布局拖拽的工具</h1><p>Magicbox</p>
<p><a target="_blank" rel="noopener" href="https://www.bootcss.com/p/layoutit/?tdsourcetag=s_pctim_aiomsg">https://www.bootcss.com/p/layoutit/?tdsourcetag=s_pctim_aiomsg</a></p>
<p><a target="_blank" rel="noopener" href="https://landing.ant.design/edit/index-cn#uid=5c9d8349a3180b0068960a3e">https://landing.ant.design/edit/index-cn#uid=5c9d8349a3180b0068960a3e</a></p>
<p>1、finereport——前端可视化布局拖拽 报表工具<br>目前市面上很流行的帆软公司的软件——finereport，功能算是前沿的，包括以上提到的功能。可做报表和大屏，包括数据整合、建模、分析、制作图表，很适合企业使用。难度不算太大，而效果也不错。</p>
<p>2、Divi Builder——前端可视化布局拖拽 设计建站工具：<br>定位是设计师和偏向于展示型的网站，如果不懂代码但有一定的审美的话，Divi 是个好工具，可以让你做出效果非常绚丽和个性的网页。</p>
<p>3、Beaver Builder——前端可视化布局拖拽 企业建站工具：<br>海狸生成器的目标市场是企业和建站服务商，因为基本上这是一直和 Elementor 处于对立面，Elementor 不允许的 Beaver Builder 都支持，更重要的是他们的策略就可以用来做基础平台工具。</p>
<p>4、Elementor—— 前端可视化布局拖拽 快速建站工具：<br>个人和快速建站首选工具，首选是因为 Elementor 功能相当齐全，免费版的基本上就够用了，但 Pro 版并不开源，同时也不能用于 SaaS 产品内，与 Beaver Builder 刚好相反；</p>
<p>5、Thrive Architect—— 前端可视化布局拖拽 外贸营销建站：<br>Thrive Architect 这个我们还没有进入深入的了解和使用，主要是 Thrive Architect 更偏向于营销和与第三方营销工具的功能集成，非常适合外贸建站，我们有未来计划，暂时还是先放一边。</p>
<p>6、Brizy——前端可视化布局拖拽 平台型建站工具：<br>Brizy 只测试过，但没有深入使用，和上面的几款前端页面生成器都是一样的，只不过 brizy 更灵活，内置了很多模块可以直接用，而且 brizy 还在构建 Cloud 云库和提供 SaaS 平台授权，这是值得我们学习的。</p>
<p>7、Visual Composer——前端可视化布局拖拽 可视化工具<br>最开始的 Visual Composer 就是现在的 WPBakery Page Builder ，也就是国外主题通常会自带集成的功能插件，然后改名后现在的 Visual Composer 进过品牌重塑后是一款网站生成器 Website Page Builder ，由于这两款工具都不符合我们的未来发展路径，这里也就不多介绍了。</p>
<p>但这一切都要基于一个好用的数据可视化平台。现在市面上流行的有FineBI、Power BI、DataV、鼎数，但权威机构IDC指出市场占有率第1的还是FineBI，使用上也都相对会比较有保障。不用担心过一年两年开发者就跑路，或者长期不更新的情况。</p>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/tips/" rel="tag">tips</a></li></ul>

    </footer>
  </div>

    
 
   
</article>

    
  </article>
  

  
  <nav class="page-nav">
    
    <a class="extend prev" rel="prev" href="/page/7/">上一页</a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/6/">6</a><a class="page-number" href="/page/7/">7</a><span class="page-number current">8</span><a class="page-number" href="/page/9/">9</a><a class="page-number" href="/page/10/">10</a><span class="space">&hellip;</span><a class="page-number" href="/page/14/">14</a><a class="extend next" rel="next" href="/page/9/">下一页</a>
  </nav>
  
</section>
</div>

      <footer class="footer">
  <div class="outer">
    <ul>
      <li>
        Copyrights &copy;
        2015-2020
        <i class="ri-heart-fill heart_icon"></i> TzWind
      </li>
    </ul>
    <ul>
      <li>
        
        
        
        由 <a href="https://hexo.io" target="_blank">Hexo</a> 强力驱动
        <span class="division">|</span>
        主题 - <a href="https://github.com/Shen-Yu/hexo-theme-ayer" target="_blank">Ayer</a>
        
      </li>
    </ul>
    <ul>
      <li>
        
        
        <span>
  <span><i class="ri-user-3-fill"></i>访问人数:<span id="busuanzi_value_site_uv"></span></s>
  <span class="division">|</span>
  <span><i class="ri-eye-fill"></i>浏览次数:<span id="busuanzi_value_page_pv"></span></span>
</span>
        
      </li>
    </ul>
    <ul>
      
    </ul>
    <ul>
      
    </ul>
    <ul>
      <li>
        <!-- cnzz统计 -->
        
        <script type="text/javascript" src='https://s9.cnzz.com/z_stat.php?id=1278069914&amp;web_id=1278069914'></script>
        
      </li>
    </ul>
  </div>
</footer>
      <div class="float_btns">
        <div class="totop" id="totop">
  <i class="ri-arrow-up-line"></i>
</div>

<div class="todark" id="todark">
  <i class="ri-moon-line"></i>
</div>

      </div>
    </main>
    <aside class="sidebar on">
      <button class="navbar-toggle"></button>
<nav class="navbar">
  
  <div class="logo">
    <a href="/"><img src="/images/ayer-side.svg" alt="Hexo"></a>
  </div>
  
  <ul class="nav nav-main">
    
    <li class="nav-item">
      <a class="nav-item-link" href="/">主页</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/archives">归档</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/categories">分类</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/tags">标签</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" target="_blank" rel="noopener" href="http://www.baidu.com">百度</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/friends">友链</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/2019/about">关于我</a>
    </li>
    
  </ul>
</nav>
<nav class="navbar navbar-bottom">
  <ul class="nav">
    <li class="nav-item">
      
      <a class="nav-item-link nav-item-search"  title="搜索">
        <i class="ri-search-line"></i>
      </a>
      
      
      <a class="nav-item-link" target="_blank" href="/atom.xml" title="RSS Feed">
        <i class="ri-rss-line"></i>
      </a>
      
    </li>
  </ul>
</nav>
<div class="search-form-wrap">
  <div class="local-search local-search-plugin">
  <input type="search" id="local-search-input" class="local-search-input" placeholder="Search...">
  <div id="local-search-result" class="local-search-result"></div>
</div>
</div>
    </aside>
    <script>
      if (window.matchMedia("(max-width: 768px)").matches) {
        document.querySelector('.content').classList.remove('on');
        document.querySelector('.sidebar').classList.remove('on');
      }
    </script>
    <div id="mask"></div>

<!-- #reward -->
<div id="reward">
  <span class="close"><i class="ri-close-line"></i></span>
  <p class="reward-p"><i class="ri-cup-line"></i>请我喝杯咖啡吧~</p>
  <div class="reward-box">
    
    
  </div>
</div>
    
<script src="/js/jquery-2.0.3.min.js"></script>


<script src="/js/lazyload.min.js"></script>

<!-- Tocbot -->

<script src="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.css">
<script src="https://cdn.jsdelivr.net/npm/justifiedGallery@3.7.0/dist/js/jquery.justifiedGallery.min.js"></script>

<script src="/dist/main.js"></script>

<!-- ImageViewer -->

<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>

    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">

        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                <!--  Controls are self-explanatory. Order can be changed. -->

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" style="display:none" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                        <div class="pswp__preloader__cut">
                            <div class="pswp__preloader__donut"></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div>
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.min.css">
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js"></script>

<script>
    function viewer_init() {
        let pswpElement = document.querySelectorAll('.pswp')[0];
        let $imgArr = document.querySelectorAll(('.article-entry img:not(.reward-img)'))

        $imgArr.forEach(($em, i) => {
            $em.onclick = () => {
                // slider展开状态
                // todo: 这样不好，后面改成状态
                if (document.querySelector('.left-col.show')) return
                let items = []
                $imgArr.forEach(($em2, i2) => {
                    let img = $em2.getAttribute('data-idx', i2)
                    let src = $em2.getAttribute('data-target') || $em2.getAttribute('src')
                    let title = $em2.getAttribute('alt')
                    // 获得原图尺寸
                    const image = new Image()
                    image.src = src
                    items.push({
                        src: src,
                        w: image.width || $em2.width,
                        h: image.height || $em2.height,
                        title: title
                    })
                })
                var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, {
                    index: parseInt(i)
                });
                gallery.init()
            }
        })
    }
    viewer_init()
</script>

<!-- MathJax -->

<!-- Katex -->

<!-- busuanzi  -->


<script src="/js/busuanzi-2.3.pure.min.js"></script>


<!-- ClickLove -->

<!-- ClickBoom1 -->

<!-- ClickBoom2 -->

<!-- CodeCopy -->


<link rel="stylesheet" href="/css/clipboard.css">

<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
<script>
  function wait(callback, seconds) {
    var timelag = null;
    timelag = window.setTimeout(callback, seconds);
  }
  !function (e, t, a) {
    var initCopyCode = function(){
      var copyHtml = '';
      copyHtml += '<button class="btn-copy" data-clipboard-snippet="">';
      copyHtml += '<i class="ri-file-copy-2-line"></i><span>COPY</span>';
      copyHtml += '</button>';
      $(".highlight .code pre").before(copyHtml);
      $(".article pre code").before(copyHtml);
      var clipboard = new ClipboardJS('.btn-copy', {
        target: function(trigger) {
          return trigger.nextElementSibling;
        }
      });
      clipboard.on('success', function(e) {
        let $btn = $(e.trigger);
        $btn.addClass('copied');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-checkbox-circle-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPIED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-checkbox-circle-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
      clipboard.on('error', function(e) {
        e.clearSelection();
        let $btn = $(e.trigger);
        $btn.addClass('copy-failed');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-time-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPY FAILED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-time-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
    }
    initCopyCode();
  }(window, document);
</script>


<!-- CanvasBackground -->


    
  </div>
</body>

</html>